【问题标题】:Same random numbers every time I run the program每次运行程序时都使用相同的随机数
【发布时间】:2011-12-06 13:52:50
【问题描述】:

我输出的随机数,每次运行我的游戏时都以相同的顺序输出。为什么会这样?

我有

#include <cstdlib> 

我正在使用它来生成随机数

randomDiceRollComputer = 1 + rand() % 6;

【问题讨论】:

标签: c++ random


【解决方案1】:

您需要播种随机数生成器:

试着把它放在程序的开头:

srand ( time(NULL) );

请注意,您需要#include &lt;ctime&gt;

这里的想法是在每次启动程序时为 RNG 播种不同的编号。通过使用时间作为种子,每次启动程序时都会得到不同的数字。

【讨论】:

  • 基本上,RNG 并不是真正随机的。他们使用一个公式来生成看似(伪)随机数。因此,他们需要一个“起点”来开始生成序列。如果不播种,它将使用相同的默认种子并每次生成相同的序列。
  • 为了获得更好的结果,在srand之后调用一次rand并丢弃返回值。事实证明,相似的种子会产生相似的第一个值,但会迅速发散。
  • 但是请注意,在大多数实现中,如果您在一秒钟内运行该程序两次,time(NULL) 将给您相同的值。这可能是也可能不是问题,具体取决于应用程序。
  • @KeithThompson:正确。当这对我来说有问题时,我会使用rdtsc 播种。但这是一个不同的故事......
  • @Mysticial:如果您的需求足够严重以至于srand(time(NULL)) 不够好,那么rand() 可能还不够好。
【解决方案2】:

你需要给随机数生成器一个种子。这可以通过获取当前时间来完成,因为这可能是某种随机的。

#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    int  r;
    srand(time(0));
    r = rand();
    return 0;
} 

【讨论】:

    【解决方案3】:

    伪随机数生成器采用一个起始数字或种子,然后从中生成序列中的下一个数字。这就是它们被称为伪随机的原因,因为如果它们始终使用相同的起始值,它们将生成与 C 标准库生成器相同的数字序列。这可以通过为生成器提供一个起始值来解决,该起始值将在下次程序运行时像当前时间一样发生变化。

    无论如何,您正在寻找的代码就像其他人所说的那样:

    srand(time(0)); //Seed the generator, give it a starting value
    

    【讨论】:

    • 不,它们被称为伪随机,因为它们在数学意义上并不是真正的随机,只是一个近似值。每次运行时生成不同数字的 PRNG 仍然是伪随机的。
    • @KeithThompson 我知道,我的意思是这就是为什么这种特定类型的 PRNG 是 PRNG。更一般地,PRNG 被称为伪随机,因为它使用确定性算法来查找序列的每个值,对吗?
    【解决方案4】:

    rand() 函数特别需要在使用给定种子播种时产生相同的数字序列(通过调用srand());每个可能的种子值指定一个序列。如果你从不调用srand(),你会得到与在调用rand()之前调用srand(1)相同的序列。

    (这不适用于不同的 C 或 C++ 实现。)

    这对于测试目的很有用。例如,如果您的程序中存在错误,您可以通过使用相同的种子重新运行它来重现它,从而保证(除非出现其他不可预测的行为)您将获得相同的伪随机数序列。

    调用srand(time(NULL)) 是获得或多或少不可预测的伪随机数的常用推荐方法。但这并不完美。如果您的程序在同一秒内运行两次,您可能会得到相同的序列,因为time()(通常)具有 1 秒的分辨率。典型的 `rand() 实现对于加密使用来说不够;攻击者很容易猜到你会得到什么数字。

    还有许多其他的随机数实现。 Linux 系统有两个伪设备,/dev/random/dev/urandom,您可以从中读取相当高质量的伪随机字节值。某些系统可能具有random()drand48() 等功能。并且有很多算法;我听说过关于Mersenne Twister 的好消息。

    对于像游戏这样的游戏,您不期望或不关心试图作弊的玩家,srand(time(NULL))rand() 可能就足够了。出于更严肃的目的,您应该向比我了解更多的人寻求建议。

    comp.lang.c FAQ 的第 13 节有一些关于伪随机数生成的非常好的信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-10
      • 2011-11-27
      • 2018-12-25
      • 1970-01-01
      • 2020-10-17
      • 2018-09-08
      相关资源
      最近更新 更多