【问题标题】:rand () function C++rand() 函数 C++
【发布时间】:2012-11-08 09:42:17
【问题描述】:

我需要生成 4 个随机数,每个都在 [-45 +45] 度之间。如果 rand%2 = 0 那么我想要结果(生成的随机数等于 -angle)。一旦生成了 4 个随机数,就需要扫描这些角度并找到一个锁(角度相交的点)。 if 语句中循环中的 -3,-2,-1,...+3 表示锁定发生在 6 度波束宽度内。代码有效。但是可以简化吗?还有目标是通过扫描两个点的仰角和方位角在两个点之间建立锁定。

  #include <iostream>
  #include <conio.h>
  #include <time.h>
  using namespace std;

  class Cscan
  {
    public:
    int gran, lockaz, lockel;

  };

  int main()
  {
     srand (time(NULL));
    int az1, az2, el1, el2, j, k;


    BS1.lockaz = rand() % 46;
    BS1.lockel = rand() % 46;
    BS2.lockaz = rand() % 46;
    BS2.lockel = rand() % 46;

    k = rand() % 2;
    if(k == 0)
            k = -1;
    BS1.lockaz = k*BS1.lockaz;

    k = rand() % 2;
    if(k == 0)
            k = -1;
    BS1.lockel = k*BS1.lockel;

            k = rand() % 2;
    if(k == 0)
            k = -1;
    BS2.lockaz = k*BS2.lockaz;

    k = rand() % 2;
    if(k == 0)
            k = -1;
    BS2.lockel = k*BS2.lockel;

    for(az1=-45; az1<=45; az1=az1+4)
    {
            for(el1=-45; el1<=45; el1=el1+4)
            {
                    for(az2=-45; az2<=45; az2=az2+4)
                    {
                            for(el2=-45; el2<=45; el2=el2+4)
                            {

           if((az1==BS1.lockaz-3||az1==BS1.lockaz-2||az1==BS1.lockaz-1||az1==BS1.lockaz||az1==BS1.lockaz+1||az1==BS1.lockaz+2||az1==BS1.lockaz+3)&&

           (az2==BS2.lockaz-3||az2==BS2.lockaz-2||az2==BS2.lockaz-1||az2==BS2.lockaz||az2==BS2.lockaz+1||az2==BS2.lockaz+2||az2==BS2.lockaz+3)&&

           (el1==BS1.lockel-3||el1==BS1.lockel-2||el1==BS1.lockel-1||el1==BS1.lockel||el1==BS1.lockel+1||el1==BS1.lockel+2||el1==BS1.lockel+3)&&

            (el2==BS2.lockel-3||el2==BS2.lockel-2||el2==BS2.lockel-1||el2==BS2.lockel||el2==BS2.lockel+1||el2==BS2.lockel+2||el2==BS2.lockel+3))
                                    {      
             cout << "locked \n" << BS1.lockaz << " " << BS1.lockel << " " << BS2.lockaz << " " << BS2.lockel <<endl
              < az1 << " " << el1 << " " << az2 << " " << el2 << endl;
                                                    k = 1;
                                            break;
                                    }
                                    if(k==1)
                                            break;
                            }
                            if(k==1)
                                    break;
                    }
                    if(k==1)
                            break;
            }
            if(k==1)
                    break;
    }
    _getch();
  }       

【问题讨论】:

  • [-45;45][0;90] 向左移动 45。看看你是否可以用它来简化你的代码。
  • 因此,如果我向左移动 45,我仍然需要选择一个随机数,即使是负范围也是如此。你能解释一下你的意思吗?
  • 我不明白你的评论。如果你在 [0,X] 中取一个随机值并删除 Y,你最终会在 [-Y,X-Y] 中得到一个随机值。
  • 谢谢。所以如果我说 BS1.lockaz= rand()%91-45 那么它不需要使用 k 吗?
  • 你怎么看?分析该语句并弄清楚它的作用。如果它可以满足您的需求,那就太好了。

标签: c++ class random srand beam-search


【解决方案1】:
BS1.lockaz = rand() % 91 - 45;
BS1.lockel = rand() % 91 - 45;
BS2.lockaz = rand() % 91 - 45;
BS2.lockel = rand() % 91 - 45;

【讨论】:

  • 你的意思是使用 BS1.lockaz = rand() % 91 - 45; BS1.lockel = rand() % 91 - 45; BS2.lockaz = rand() % 91 - 45; BS2.lockel = rand() % 91 - 45;生成负角?
【解决方案2】:

以度为单位的整数角?非常值得怀疑。像角度这样“物理”的东西通常最好用浮点数表示,所以我首先要改变

typedef double angle;

struct Cscan {  // why class? This is clearly POD
  int gran; //I don't know what gran is. Perhaps this should also be floating-point.
  angle lockaz, lockel;
};

乍一看,这似乎使它变得更加困难,因为% 的随机范围选择不再有效,也没有太多用处来比较浮点数是否相等。 然而,这是一件好事,因为所有这些实际上都是非常糟糕的做法。

如果您想继续使用rand() 作为随机数生成器(尽管我建议使用std::uniform_real_distribution),请编写一个函数来执行此操作:

const double pi = 3.141592653589793;  // Let's use radians internally, not degrees.
const angle rightangle = pi/2.;      //  It's much handier for real calculations.

inline angle deg2rad(angle dg) {return dg * rightangle / 90.;}

angle random_in_sym_rightangle() {
  return rightangle * ( ((double) rand()) / ((double) RAND_MAX) - .5 );
}

现在你就可以了

BS1.lockaz = random_in_sym_rightangle();
BS1.lockel = random_in_sym_rightangle();
BS2.lockaz = random_in_sym_rightangle();
BS2.lockel = random_in_sym_rightangle();

然后你需要做这个范围检查。这又是要放入一个专用函数的东西

bool equal_in_margin(angle theta, angle phi, angle margin) {
  return (theta > phi-margin && theta < phi+margin);
}

然后您对锁进行详尽的搜索。这绝对可以更有效地完成,但这是一个算法问题,与语言无关。坚持for 循环,您仍然可以通过避免这种显式的中断检查来使它们看起来更好。一种方法是很好的老goto,我建议你把它放在一个额外的函数中,完成后返回

#define TRAVERSE_SYM_RIGHTANGLE(phi) \
  for ( angle phi = -pi/4.; phi < pi/4.; phi += deg2rad(4) )

int lock_k  // better give this a more descriptive name
      ( const Cscan& BS1, const Cscan& BS2, int k ) {
  TRAVERSE_SYM_RIGHTANGLE(az1) {
    TRAVERSE_SYM_RIGHTANGLE(el1) {
      TRAVERSE_SYM_RIGHTANGLE(az2) {
        TRAVERSE_SYM_RIGHTANGLE(el2) {
          if( equal_in_margin( az1, BS1.lockaz, deg2rad(6.) )
               && equal_in_margin( el1, BS1.lockel, deg2rad(6.) )
               && equal_in_margin( az2, BS1.lockaz, deg2rad(6.) )
               && equal_in_margin( el2, BS2.lockel, deg2rad(6.) ) ) {
            std::cout << "locked \n" << BS1.lockaz << " " << BS1.lockel << " " << BS2.lockaz << " " << BS2.lockel << '\n'
               << az1 << " " << el1 << " " << az2 << " " << el2 << std::endl;
            return 1;
          }
        }
      }
    }
  }
  return k;
}

【讨论】:

  • 嗨,我确实尝试过这段代码,但我需要解释一下。我是 C++ 新手。我收到一个错误: int lock_k ( const CScan& BZ1, const CScan& BZ2, init k ) 。我们必须在哪里声明 int main() ?你在 int lock_k 中指出的 BZ1 和 BZ2 // 最好给它一个更具描述性的名称 ( const CScan& BZ1, const CScan& BZ2, init k ) 是否与 BS1 和 BS2 相同?
  • 这一行也出现错误:inline angle deg2rad(angle dg) {return dg * rightangle / 90}
  • 非常感谢!还有一个参数需要添加,即范围。范围应在 20m 到 800m 之间变化,步长为 20。对于这些范围中的每一个,都需要确定锁定。我应该在哪里包含这个?
  • 什么“范围”?请用数学方法解释。
  • 好的,我会解释的。同时我尝试用我现有的代码修改你的代码。 ideone.com/jrDzF7
猜你喜欢
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-29
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多