Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ rand()在每次函数调用时产生相同的结果(使用srand(时间(0))_C++_Random - Fatal编程技术网

C++ rand()在每次函数调用时产生相同的结果(使用srand(时间(0))

C++ rand()在每次函数调用时产生相同的结果(使用srand(时间(0)),c++,random,C++,Random,我有一个类的成员函数,它应该生成一个范围内的随机数。为此,我使用rand()函数。该函数生成一个如下所示的随机数: unsigned seed; seed = time(0); srand(seed); std::cout << "Random Number: "<< rand() << std::endl; 每次我调用它都是一致的。我做错了什么?伪随机数生成器基本上必须通过一组统计测试,以确保它们作为一组数字“足够随机”。但

我有一个类的成员函数,它应该生成一个范围内的随机数。为此,我使用rand()函数。该函数生成一个如下所示的随机数:

    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