C++ rand()在每次函数调用时产生相同的结果(使用srand(时间(0))
我有一个类的成员函数,它应该生成一个范围内的随机数。为此,我使用rand()函数。该函数生成一个如下所示的随机数:C++ rand()在每次函数调用时产生相同的结果(使用srand(时间(0)),c++,random,C++,Random,我有一个类的成员函数,它应该生成一个范围内的随机数。为此,我使用rand()函数。该函数生成一个如下所示的随机数: unsigned seed; seed = time(0); srand(seed); std::cout << "Random Number: "<< rand() << std::endl; 每次我调用它都是一致的。我做错了什么?伪随机数生成器基本上必须通过一组统计测试,以确保它们作为一组数字“足够随机”。但
unsigned seed;
seed = time(0);
srand(seed);
std::cout << "Random Number: "<< rand() << std::endl;
每次我调用它都是一致的。我做错了什么?伪随机数生成器基本上必须通过一组统计测试,以确保它们作为一组数字“足够随机”。但当然,它实际上不是随机的。调用
srand(seed)
使用一些种子
基本上会生成一组数字,如果通过这些测试,这些数字看起来“足够随机”
通过多次使用相同的seed
调用srand(seed)
,可以有效地一次又一次地生成相同的集合并获取其中的第一个值
调用srand(seed)
一次,然后调用rand()
以获取随机数集中的下一个值。或者每次需要使用不同的(随机)种子调用srand(seed)
如果你在linux上,你也可以使用/dev/uradom
来获取一个随机数-内核一直从环境中获取信号/噪声来为它生成“熵”,据说这比psuedorandom数字生成器算法更好。(将我的评论转换为答案)
对于大多数应用程序,在运行程序的过程中,您只需要对rand
进行一次种子设定。多次种子设定需要获得不同的随机种子,很容易搞糟
在您的例子中,time
函数通常返回分辨率为秒的内容(尽管如此)。因此,如果在同一秒内调用time
两次,可能会返回相同的值。这就解释了为什么会得到重复的值:使用相同的值对随机化器进行两次种子设定,然后立即查询随机数
最好的解决方法是只给随机化程序种子设定一次。通常,您可以在main
中执行此操作
如果确实要多次为随机化程序设定种子,请确保使用的种子将非常随机。否则,可能会发生类似情况。
srand
函数在程序中只应调用一次(大多数情况下,并非所有情况下)。如果要重新设定种子,则应使用不同的种子编号。因为rand()
函数是伪随机数生成器。换句话说,rand()
会为您提供一个计算出的编号
在C++11之后,您可以使用很多功能强大的随机数生成库。请参阅:在一个程序中多次重新设置随机数发生器的种子是非常罕见的-通常您会提前执行一次,然后再也不碰它。并且
时间
通常具有1秒的分辨率,因此如果您以相同的方式生成两个随机值,则第二,你会看到这一点。如果我应该只播一次种子,我应该在我的main中做吗?我想我不应该在类构造函数中做,因为它会被调用两次。只要做了上面的操作,它就成功了!谢谢!John,你可以在构造函数中进行惰性初始化,比如static bool first=true;If(first){1} false;SRAND(时间(NulLPTR));} 但是<>代码>主< /Cord>建议可能更好,因为您的类可能不是唯一使用随机数的。如果您标记它[C++ ],考虑使用来自因斯泰德的东西每次都不是同一个种子。时间(0)以32位或64位整数类型给出当前时间我听到了你的意思,但正如上面的评论员所解释的,快速连续调用time(0)实际上返回相同的数字。此外,OP不调用srand(time(0)),OP调用srand(seed),其中seed在某个点被设置为time(0)。“srand
函数在程序中只能调用一次。"这句话太难了,这说明它是不真实的。很少有需要重新植入随机数生成器的情况。尽管我承认您可能在编程方面有过职业生涯,但从未遇到过这种情况。@user4581301就像多线程的情况一样?哦,我甚至不想想象……请注意,在与“代码> >代码>相同的接口,但在很多方面都更好。你知道吗?我从来没有在多线程程序中使用过<代码> Srand < /Cult> /Cuth> Rand < /Cord>。必须查看它是否在C++ 11之后是线程安全的。看起来它没有保证。现在,任何需要重新移植的情况下,几乎可以肯定使用更好的RAN。dom编号生成器。
Random Number: 1321638448
Random Number: 1321638448