C ++中的顺序随机数?

时间:2013-08-19 12:04:54

标签: c++ random numbers

我正在寻找一种在C ++中快速生成两个随机数的方法。代码用于死亡,需要在滚动时生成随机数。我的代码目前看起来像这样:

Die::Die() {
    srand(time(NULL));
}

void Die::roll() {
    value = rand() % 6 + 1;
}

如果我使用此代码创建两个对象,则srand()作为静态(非基于实例)函数,将为所有对象生成新种子。我也尝试过这样做:

void Die::roll() {
    srand(time(NULL));
    value = rand() % 6 + 1;
}

而不是在构造函数中使用它,但如果我快速调用它们如下:

die0->roll();
die1->roll();

他们的价值观通常是平等的。有没有什么方法可以让它每次都随机?感谢你的帮助。 :)

4 个答案:

答案 0 :(得分:4)

假设程序运行得足够快,时间(以秒为单位)通常是相同的,这意味着你的种子将是相同的,这意味着你的随机值是相同的。 正如评论者所说,在其他地方做随机种子(比如程序或线程的开头)。

答案 1 :(得分:1)

问题是,如果队列在时间上彼此足够接近,那么你将使用相同的值为rng播种,因此每个种子后得到的第一个值将是相同的。为避免这种情况,您可以确保仅播种一次。例如,您可以从Die类中删除srand,并在第一次使用Die之前的某个时候播种。

或者,如果你不希望Die的使用者负担调用srand的负担,你可以将srand保留在Die的构造函数中,但要防止使用静态bool多次调用它。

Die::Die()
{
  static bool seeded = false;
  if (!seeded)
  {
    srand(time(NULL));
    seeded = true;
  }
}

请注意,此srand仍然可以影响srand()和rand()的其他类,但这可能无关紧要。但是如果你需要在你定义的多个类中使用随机数,你可以考虑创建一个RNG单例来为你生成数字。

答案 2 :(得分:1)

最不容易出错的方法是使用uniform_int_distribution标头中的random。这也避免了modulo bias,这是基本的例子:

#include <iostream>
#include <random>

 class Die
 {
   public:
     template <class Generator>
     void roll( Generator &g )
     {
         std::uniform_int_distribution<int> dist(1,6);
         std::cout << dist(g) ;
     }

   private:

 } ;

int main()
{
    std::random_device rd;

    std::mt19937 e1(rd());

    Die d1, d2 ;

    for (int n = 0; n < 10; ++n) {
            d1.roll( e1 ) ;
            std::cout << " , " ;
            d2.roll( e1 ) ;
            std::cout << std::endl ;
    }
}

或者,您也可以使用static成员,正如詹姆斯建议的那样:

class Die
{
   public:
     Die()  {} ;

     void roll()
     {
         std::uniform_int_distribution<int> dist(1,6);
         std::cout << dist(e1) ;
     }

   private:
      static std::random_device rd;    
      static std::mt19937 e1 ;
} ;

答案 3 :(得分:0)

正如其他人所说,你不想更多地重新设置发电机 不止一次。如果Dierand的唯一用户(或者即使它 不是),您可以使用名称空间范围内的变量来播种它:

int seeded = (srand( time( NULL ) ), rand());

这是否是一个好主意取决于;它成功了 不可能复制一段代码进行调试 例如,目的。如果这是一个问题,你会想要1) 记录您使用的种子,2)在命令行中添加一个选项 指定种子;后者意味着从中调用srand main

(另请注意,我已经添加了对rand()的调用 初始化。在至少一个广泛实施中, 第一次调用rand()会返回种子,这意味着它可以 非常可预测。)