随机数不是那么随机

random numbers not so random

本文关键字:随机 随机数      更新时间:2023-10-16

我在类中有一个方法,如下所示...

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 次迭代之间甚至没有一点区别。任何想法都值得赞赏!谢谢!

您需要

在随机发生器函数之外调用srand()一次。否则,每次使用完全相同的时间值重新设定随机数生成器种子,从而产生相同的初始"随机"值。

你每次循环迭代都使用相同的种子调用srand(),因为时间实际上没有时间改变。确保只调用一次,一切正常。

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); 
   }
};