【问题标题】:C++ `srand()` function producing a pattern?C ++`srand()`函数产生模式?
【发布时间】:2019-03-21 12:55:08
【问题描述】:

C++ 新手并遵循初学者教程here。请参阅标题为C++ 中的随机数 的部分。完全使用给出的代码:

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

int main () {
   int i,j;

   // set the seed
   srand( (unsigned)time( NULL ) );

   /* generate 10  random numbers. */
   for( i = 0; i < 10; i++ ) {
      // generate actual random number
      j = rand();
      cout <<" Random Number : " << j << endl;
   }

   return 0;
}

我正在用time() 播种srand()(用g++ 编译),因此生成的结果应该是完全随机的。但是,这是我得到的结果:

$ ./a.out
 Random Number : 1028986599
 Random Number : 491960102
 Random Number : 561393364
 Random Number : 1442607477
 Random Number : 813491309
 Random Number : 1467533561
 Random Number : 986873932
 Random Number : 1373969343
 Random Number : 411091610
 Random Number : 761796871
$ ./a.out
 Random Number : 1029003406
 Random Number : 774435351
 Random Number : 36559790
 Random Number : 280067488
 Random Number : 1957600239
 Random Number : 1937744833
 Random Number : 1087901476
 Random Number : 684336574
 Random Number : 1869869533
 Random Number : 621550933
$ ./a.out
 Random Number : 1029020213
 Random Number : 1056910600
 Random Number : 1659209863
 Random Number : 1265011146
 Random Number : 954225522
 Random Number : 260472458
 Random Number : 1188929020
 Random Number : 2142187452
 Random Number : 1181163809
 Random Number : 481304995

从每次./a.out 执行时生成的第一个数字可以看出,10 循环中的第一个数字在每次执行时都在增加。它似乎总是大约1.02百万。进一步的测试表明,这种模式始终存在,这并非巧合。

我只能假设由于种子time() 而增加,它总是在增加。但这表明rand() 函数并不是真正随机的并且是可预测的。

【问题讨论】:

  • rand() 是垃圾。对它的随机性没有要求,它很可能只是增加并符合要求。请改用&lt;random&gt; 中的新功能。
  • 为什么每个 C++ 教程都用标准输出教授 C?您应该改用&lt;random&gt;
  • @FrançoisAndrieux 我想你是想回应五月的状态
  • @thestateofmay 每个循环都调用srand 是绝对不正确的。值得注意的是,time 的分辨率非常低,您可能会使用相同的种子调用srand。每次迭代都会得到相同的数字。您正确使用了srandrand,它们只是不是很好的功能,应该避免使用。如果教程建议它们,它要么非常过时,要么不太好。编辑:不幸的是,大多数 c++ 教程要么属于该类别,要么正在教授带有少量 c++ 特性的 c。
  • @zzxyz: That question 与原始 rand 输出几乎没有关系,正如其上接受的答案所示;他们以触发模式的方式使用输出,PRNG 的任何改进都不会有意义地改变结果。

标签: c++ random srand


【解决方案1】:

但这表明 rand() 函数并不是真正随机的并且是可预测的。

是的,这完全正确。通常,rand 是用一个非常简单的伪随机数生成器实现的。当需要真正随机或不可预测的数字时,不适合使用rand

在后台,您的实现可能使用Linear congruential generator,并且您的三个示例都在相同的线性区间内,至少对于第一个输出。

【讨论】:

  • 教程里特别说“第一个是rand(),这个函数只会返回一个伪随机数,解决方法是先调用srand()函数。”它在提供的代码示例中做了什么。我只能假设每个循环都需要调用 srand() 或者本教程是错误的。
  • @thestateofmay 该教程具有误导性。如果你不打电话给srand,你每次都会得到完全相同的序列。如果您调用srand,您将每次从不同的点开始序列,但这意味着什么取决于您平台的rand 实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多