随机数不是那么随机

时间:2012-04-11 17:35:21

标签: c++ random

我在课堂上有一个方法如下......

class foo{
   int bar::randomNum10to50(){
      srand (time(NULL));
      int random10to50 = rand()%50+10; 
      return random10to50;
   }
}

然而,当我从main调用它时(只是为了检查输出,因为我没有得到我预期的程序中的行为),就像这样....

foo create;
for (int i=0; i<20;i++){
    cout<<create.randomNum10to50()<<endl;
}
每次运行时它都是完全相同的数字(即9,9,9,9,9,......;下一次运行:43,43,43,43,.....)我不喜欢我知道出了什么问题。 代码运行得非常快,所以我认为可能是问题,但我不明白为什么在20次迭代之间没有差别。任何想法都表示赞赏!谢谢!

3 个答案:

答案 0 :(得分:20)

您需要在随机函数功能的, 之外调用srand() 。否则,每次使用完全相同的时间值对随机数生成器重新播种,产生相同的初始“随机”值。

答案 1 :(得分:6)

在每次循环迭代中,您使用相同的种子调用srand(),因为时间实际上没有时间更改。确保只调用一次,一切都应该有效。

答案 2 :(得分:3)

Cody Gray已经说过你在这里做错了什么,但这里有一个用<random>库做这个的例子:

#include <random>

std::mt19937 make_seeded_engine() {
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
    return std::mt19937(seed);
}

class foo {
   std::mt19937 engine;

public:
   foo() : engine(make_seeded_engine()) {}

   int randomNum10to50(){
      return std::uniform_int_distribution<>(10,50)(engine); 
   }
};

foo create;
for (int i=0; i<20;i++){
    cout << create.randomNum10to50() << '\n';
}

请注意rand()%50 + 10产生的数字范围是10到59,而不是10到50. uniform_int_distribution更好,因为你给它的范围是你得到的范围,所以你不太可能弄乱它。同样使用uniform_int_distribution可以获得无偏见的结果,而rand()%50+10有一些轻微的偏见。


如果你的编译器有更多的C ++ 11支持,你可以这样做:

class foo{
   std::mt19937 engine = make_seeded_engine();

public:
   int randomNum10to50(){
      return std::uniform_int_distribution<>(10,50)(engine); 
   }
};