随机数发生器 - 为什么每次都播种

时间:2013-12-17 14:33:04

标签: c++ c

我是c和c ++的新手。在我用来编程的语言java中,它很容易实现随机数生成。只需从名为Math的类中调用静态随机方法。

int face = ((int)(Math.random() * 6) + 1);

模拟掷骰子......

在c和c ++中你必须通过调用srand-function来“播种随机数生成器”

srand ( time(NULL) );

这样做有什么意义 - 我的意思是每次运行代码时都必须为随机数生成器播种?

7 个答案:

答案 0 :(得分:25)

给定相同的种子,伪随机数生成器每次都会产生相同的序列。因此,每次运行时,您是否需要不同的伪随机数序列。

这实际上取决于您的需求。有时您想重复一个序列。而当你不这样做的时候。您需要了解每个特定应用程序的需求。

你必须做的一件事是在生成单个序列时反复播种。这样做很可能会破坏序列的分布。

答案 1 :(得分:12)

通常称为随机数生成器的实际上是伪随机数生成器。这通常意味着如果您为该序列提供“密钥”,您可以生成相同的随机序列,称为“种子”。当您希望测试基于随机化的算法时,这非常有用,并且您需要确保可重复的结果。

如果您没有“播种”您的随机数生成器,默认情况下会使用某些(通常基于系统时间)随机数播种,因此每次运行时都会生成不同的序列你的计划。

答案 2 :(得分:10)

如果你没有为生成器播种,那么每次运行程序时它都会有相同的种子,每次随机数序列都是相同的。

另请注意,您只应在程序开始时为生成器播种一次。

答案 3 :(得分:8)

优点是您可以通过提供相同的种子重复随机数序列。

游戏精英使用它来存储整个世界,由数千颗星组成,作为单个数字。 为了第二次生成完全相同的世界,刚刚提供了相同的种子。

答案 4 :(得分:4)

伪随机数生成器需要种子来生成与先前的随机数序列不同的随机数序列(并非总是如此)。如果您不想重复序列,则需要为伪随机数生成器设定种子。

尝试这些代码并查看差异 没有种子:

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

int main()
{
        printf("%d", rand()%6 + 1);
}  

种子:

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

int main()
{
        srand(time(NULL));
        printf("%d", rand()%6 + 1);
}

答案 5 :(得分:1)

在C / C ++中,掷骰子会像这样模拟:

int face = (rand() % 6) + 1);
                   ^
                   |___________ Modulo operator

% 6将随机数限制为 0到5 ,并使+ 1偏移限制,因此它变为 1到6

答案 6 :(得分:1)

随机数生成器并不是真正随机的:假设你用12种子种子并制作100个随机数,重复这个过程并再次用12种子播种并再制作100个随机数,它们将是相同的。

我附加了一个2个小块的小样本,每个20个条目,种子为12,以便在创建它们的代码之后立即说明:

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
    srand(12);
   for (int i =0;i<100; i++)
   {
       cout << rand() << endl;
   }
   return 0;
}

two randomly generated sequences both seeded with 12

为了避免这种重复,使用更独特的值是常见的,因为时间总是在变化,并且两个程序在完全相同的时间生成随机序列的可能性很小(特别是在毫秒级时)人们可以合理安全地将时间用作几乎独特的种子。

要求:只需要按照您需要生成的唯一随机序列进行一次播种。

但是,这有一个意想不到的上升/下降: 如果知道生成第一个序列的确切时间,则可以通过手动输入种子值来重新生成确切序列,从而使随机数生成器以与之前相同的方式逐步执行其过程(此存储随机序列是一个好处,也是保持随机序列的缺点。)