我在C中编写了一个简单的随机数生成器。int l
是下限,int u
是上限。
它工作得很好,但我有一个关于播种它的问题。如果我要在循环中运行它,time(NULL)
不会足够快地更改种子值,以防止获得完全相同的连续系列随机数。
我想知道其他人怎么可能解决这个问题。我在网上找到的所有例子都使用time(NULL)
作为种子值生成器。
int generateRandom(int l, int u)
{
srand(time(NULL));
int r = rand() % ((u - l) + 1);
r = l + r;
return r;
}
如果我要将这些代码行紧挨着运行,Rand1
和Rand2
将完全相同。
printf("Rand1 = %d\n", generateRandom(10, 46));
printf("Rand2 = %d\n", generateRandom(10, 46));
答案 0 :(得分:21)
srand(time(NULL))
应该只运行一次以初始化PRNG。在应用程序启动时在Main中执行此操作。
<强>解释强>
PRNG(伪随机数发生器)根据所使用的算法生成确定的数字序列。给定的算法将始终从给定的起点(种子)产生相同的序列。如果您没有明确地为PRNG设定种子,那么每次运行应用程序时它通常都会从相同的默认种子开始,从而导致使用相同的数字序列。
要解决此问题,您需要在每次运行应用程序时使用不同的种子(以提供不同的序列)为PRNG播种。通常的方法是使用time(NULL)
根据当前时间设置种子。只要您不在一秒钟内启动应用程序的两个实例,就可以保证不同的随机序列。
每次需要新的随机数时都不需要对序列进行播种。我不确定这一点,但我觉得根据所使用的PRNG算法重新播种每个新数字实际上可能会导致结果序列中的随机性降低。
答案 1 :(得分:7)
在主要开始时播种一次。如果你在同一秒内重新设置太快,你最终会获得相同的数字。
答案 2 :(得分:6)
srand( (unsigned) time(NULL) * getpid());
产生更多样化的随机集(在OSX 10.8上),包括短周期测试。
答案 3 :(得分:5)
不要每次都播种,只在节目的开头。
此外,许多书籍建议不要使用C-lib标准随机函数。如果您需要良好的伪随机数,那么Press等人的数字食谱,第3版就有一个很好的算法。版。
答案 4 :(得分:4)
我假设您从另一个函数generateRandom
或其他函数调用main
函数。
如果在函数内声明种子,则会重置该函数。重置该功能,将使相同的数字出现几次,相同的秒数。
将srand(time(NULL));
移动到main函数将解决问题。
答案 5 :(得分:1)
如果您使用的是不同的流程,请使用(rand()+getpid())%range;
我用它来测试同一程序的随机值每秒多次(如果你做rand数字,退出程序并再次运行很快,数字将是相同的)