2011-10-13 109 views
20

我输出的随机数,每次运行游戏时都以相同的顺序输出。这是为什么发生?每次运行程序时都使用相同的随机数

#include <cstdlib> 

和现在用这个来产生随机数

randomDiceRollComputer = 1 + rand() % 6; 
+0

请参阅http://en.wikipedia.org/wiki/Pseudorandom_number_generator – DuckMaestro

回答

26

您需要种子的随机数发生器:

尝试把此在的开始程序:

srand (time(NULL)); 

请注意,您将需要#include <ctime>

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

+0

嗯播种方面究竟意味着什么? – mystycs

+4

基本上,RNG并不是真正的随机。他们使用一个公式来生成看似(伪)的随机数。因此,他们需要一个“起点”来开始生成一个序列。如果您没有种子,它将使用相同的默认种子并每次生成相同的序列。 – Mysticial

+2

为了获得更好的结果,请在'srand'后面调用'rand'并丢弃返回值。事实证明,类似的种子产生了类似的第一个值,但它迅速发散。 –

7

您需要给随机数生成器一个种子。这可以通过考虑当前时间来完成,因为这是希望的某种随机。

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

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

伪随机数发生器取一个起始数字或种子,然后从这个序列中产生下一个数字。这就是为什么它们被称为伪随机数的原因,因为如果它们始终使用相同的起始值,它们将生成与C标准库生成器相同的数字序列。这可以通过给发生器一个初始值来修复,该值将在下一次程序运行时改变,如当前时间。

无论如何,你看像其他人所说的代码是:

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

不,他们'我们称之为伪随机数,因为它们在数学意义上并不是真正的随机数,只是一个近似值。每次运行时都会生成不同数字的PRNG仍然是伪随机数。 –

+0

@KeithThompson我知道,我的意思是这就是为什么这种特定类型的PRNG是PRNG。更一般地说,PRNG被称为伪随机,因为它使用确定性算法来查找序列的每个值,是否正确? – jgon

1

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部分有关于伪随机数生成的一些非常好的信息。

相关问题