即使播种

时间:2017-02-21 23:56:32

标签: c random

这很可能是机器相关的问题,但我无法弄清楚可能出现的问题。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char** argv) {

  srand(time(NULL));
  int r1 = rand();
  int r2 = rand();
  printf("%d %d\n", r1, r2);
}

我使用

编译上面的代码
gcc randd.c

然后手动运行几次,第一个数字看起来非常相似,而第二个看起来是随机的:

1025720610 1435057801
1025737417 1717533050
1025754224 2000008299
1025771031 134999901
1025787838 417475150

rand()的第一次调用似乎与时间密切相关,并且随着时间的推移严格增加。关于为什么会发生这种情况或如何解决它的任何想法?

这在OSX 10.11上发生

2 个答案:

答案 0 :(得分:2)

  1. rand()非常糟糕,如果可能请避免使用它。在任何好的RNG中,即使种子接近(汉明距离),第一个值也将与随机无法区分。在rand中情况并非如此。
  2. 如果你必须使用rand然后播种,最好使用比时间更高的熵,并多次拨打rand()而不是重新播种 - 重新播种。
  3. 例如2,考虑:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(int argc, char** argv) {
      int t=time(NULL);
      srand(t);
    
      for(int i=0; i < 10; i++) {
        float r = (float)rand()/(float)(RAND_MAX);
        printf("%f\n", r);
      }
    }
    

    结果:

    0.460600
    0.310486
    0.339473
    0.519799
    0.258825
    0.072276
    0.749423
    0.552250
    0.665374
    0.939103
    

    它仍然是一个糟糕的RNG但是当你允许它使用内部状态而不是给它另一个类似的种子时,至少范围更好。

答案 1 :(得分:1)

这正是您应该期待的。没有&#34;随机数&#34;。只有序列的数字具有随机分布。 rand()函数生成了这样的序列,但是你没有给它机会,因为你不断重新播种它。 rand()生成的第一个数字很可能只是种子或种子本身的某些功能。一些rand()函数可能会对种子进行哈希以隐藏它,但这并不能使它们更好,因为rand()的契约是生成一个随机序列

如果您需要一系列可以在运行多个程序后幸存的随机数,您必须执行以下操作:(a)编写一次调用srand()一次的程序,然后调用rand()许多时间,让你的其他程序通过IPC询问该程序的随机数; (b)使用/dev/urandom之类的东西; (c)使用类似random.org的内容。