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

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

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

模拟掷骰子……

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

 srand ( time(NULL) ); 

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

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

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

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

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

如果您没有“播种”随机数生成器,默认情况下会为其添加一些 (通常基于系统时间)随机数,因此每次运行程序时都会生成不同的序列。

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

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

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

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

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

尝试这些代码,看看差异。
没有种子:

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

种子:

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

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

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

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

两个随机生成的序列,均为12个种子

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

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

然而,有一个意想不到的上/下方:如果知道生成第一个序列的确切时间,那么通过手动输入种子值可以在将来重新生成确切的序列,从而导致随机数字生成器以与以前相同的方式逐步完成其过程(这是存储随机序列的优点,以及保留其随机性的缺点)。

在C / C ++中,骰子卷将被模拟如下:

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

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