我在C ++中编写了一个函数,该函数使用time.h
的系统时间作为种子,并在两个指定值之间返回一个伪随机数。
#include <time.h>
int randInt(int min, int max)
{
int nSeed = time(NULL);
int nRandom = nSeed * 13;
nRandom = nRandom % (max + 1);
nRandom += min;
return nRandom;
}
该功能正是它应该做的事情(据我所知)。但是,当我反复调用该函数时,例如,当使用for
循环用伪随机数填充数组时,几乎没有时间过去,因此种子是相同的,使得数组中的每个数字相同。我怎么能解决这个问题?有没有办法从系统中获得更小的精度?或者我是否完全以错误的方式解决这个问题?
答案 0 :(得分:3)
你应该获得种子(例如时间)一次,然后通过重复应用步进函数生成几个值。没有,你的“PRNG”只是一个哈希函数,适用于种子生成,通常不是很随机。将种子与阶梯函数分离还允许确定性操作(固定种子)以进行调试或可重现的结果。
答案 1 :(得分:1)
生成一系列随机值时,不得重复播种PRNG。只播种一次,通常是在你的节目开始时。
您遇到的问题是错误重播的明显后果。更严重的问题是重播可能会破坏PRNG的分布特性。
PRNG的一个大问题是,您不存储以前生成的值。每次采样时,这都会导致您重新播种。解决方案是记住PRNG生成的先前值,并从那开始而不是time(NULL)
。
答案 2 :(得分:1)
正如其他人所指出的那样,你不应该为每次调用你的函数重新设置。
但是,对于randInt
的两次调用,获得相同数字的具体问题更可能是因为time
在秒中返回时间。因此,对于一秒钟,对函数的所有调用都将使用完全相同的种子,从而返回完全相同的值。
但我强烈建议使用属于C ++ 11或<random>
的boost::random,这对于旧版本的C ++基本相同
答案 3 :(得分:0)
你可以简单地添加一些延迟或睡眠,以便在种子中没有相同的时间,但正如其他人建议你不应该生成自己的PRNG,你可能想要添加一些鼠标位置,一些数据包接收,或其他因素,以增加随机性,但它仍然不是生成随机数的好方法。