我非常喜欢能够重复生成同一组伪随机数据,特别是在调整实验代码时。通过观察,我会说rand()似乎每次都给予相同的数字序列 *。对于同一台机器/不同机器/不同体系结构上的重复执行,是否可以保证做到这一点?
rand()
tjvv9vkg1#
是的,假定程序的环境相同。从C标准§7.20.2.2/2,srand函数使用该参数作为种子,生成一个新的伪随机数序列,该序列将由对rand的后续调用返回。**如果随后使用相同的种子值调用srand,则将重复该伪随机数序列。**如果在对srand进行任何调用之前调用rand,将产生与当以种子值1第一次调用srand时相同的序列。当然,这是假设它使用相同的实现细节(即相同的机器,相同的库在相同的执行周期)。C标准没有强制要求标准的随机数生成算法,因此,如果你用不同的C标准库运行程序,你可能会得到不同的随机数序列。如果你需要一个可移植的、有保证的随机数序列,并且有一个给定的种子,请参阅问题Consistent pseudo-random numbers across platforms。
srand
rand
vjrehmav2#
它保证为传递给srand()的相同种子给予相同的序列-但 * 仅在程序的单次执行期间 *。通常,如果实现在行为上有选择,则对于该选择在后续执行中保持相同没有特定要求。在每次程序启动时挑选“主种子”,并使用该主种子以每次程序启动时不同的方式扰动伪随机数生成器的实现将是一致的。如果您希望获得更多的确定性,则应在程序中使用特定参数实现PRNG。
srand()
twh00eeo3#
不,不,不C标准说:如果随后使用相同的种子值调用srand,则应重复伪随机数序列。但是没有任何地方说明伪随机数序列实际上是什么--所以它在不同的实现中不同。唯一的保证是rand()将为给定的种子 * 和给定的实现 * 给予相同的数字序列。不能保证该序列在不同的机器或不同的体系结构之间是相同的--几乎可以肯定不会是这样。
i34xakig4#
如果需要使用完全相同的伪随机数集进行实验,可以使用srand生成一个长的随机数序列,并将其写入文件/数据库。然后,编写一个可移植的“随机数生成器”函数,从该文件顺序返回值。这样,您可以确保使用相同的输入数据,而与平台、srand实现或种子值无关。
thtygnil5#
当切换到不同的机器/运行时/任何你可能会运气不好。还有另一个可能的选择drand48系列的函数。这些被规范化为在所有机器上使用相同的算法。
drand48
nom7f22z6#
如果您使用的是UNIX/Linux环境,您可以在手册页中看到drand 48()和srand 48()。如果您不是UNIX/Linux环境,您可以看到C语言的online manuals。原型可以在**/usr/include/stdlib.h**中找到。第一个原型使用在模拟中经常使用的线性同余法。如果你给srand 48()提供相同的种子,也就是srand 48(2),然后把dran 48()放在一个for循环中,那么每次的序列都是相同的。
include stdio.h include stdlib.h double drand48(); int main(void){ int i; double rn; srand48(2); for(i=0; i<10; i++){ randNum = drand48(); printf("%.6l\n", randNum); return 0; }
6条答案
按热度按时间tjvv9vkg1#
是的,假定程序的环境相同。从C标准§7.20.2.2/2,
srand
函数使用该参数作为种子,生成一个新的伪随机数序列,该序列将由对rand
的后续调用返回。**如果随后使用相同的种子值调用srand
,则将重复该伪随机数序列。**如果在对srand
进行任何调用之前调用rand
,将产生与当以种子值1第一次调用srand
时相同的序列。当然,这是假设它使用相同的实现细节(即相同的机器,相同的库在相同的执行周期)。C标准没有强制要求标准的随机数生成算法,因此,如果你用不同的C标准库运行程序,你可能会得到不同的随机数序列。
如果你需要一个可移植的、有保证的随机数序列,并且有一个给定的种子,请参阅问题Consistent pseudo-random numbers across platforms。
vjrehmav2#
它保证为传递给
srand()
的相同种子给予相同的序列-但 * 仅在程序的单次执行期间 *。通常,如果实现在行为上有选择,则对于该选择在后续执行中保持相同没有特定要求。在每次程序启动时挑选“主种子”,并使用该主种子以每次程序启动时不同的方式扰动伪随机数生成器的实现将是一致的。
如果您希望获得更多的确定性,则应在程序中使用特定参数实现PRNG。
twh00eeo3#
不,不,不
C标准说:
如果随后使用相同的种子值调用srand,则应重复伪随机数序列。
但是没有任何地方说明伪随机数序列实际上是什么--所以它在不同的实现中不同。
唯一的保证是
rand()
将为给定的种子 * 和给定的实现 * 给予相同的数字序列。不能保证该序列在不同的机器或不同的体系结构之间是相同的--几乎可以肯定不会是这样。i34xakig4#
如果需要使用完全相同的伪随机数集进行实验,可以使用
srand
生成一个长的随机数序列,并将其写入文件/数据库。然后,编写一个可移植的“随机数生成器”函数,从该文件顺序返回值。这样,您可以确保使用相同的输入数据,而与平台、srand
实现或种子值无关。thtygnil5#
当切换到不同的机器/运行时/任何你可能会运气不好。还有另一个可能的选择
drand48
系列的函数。这些被规范化为在所有机器上使用相同的算法。nom7f22z6#
如果您使用的是UNIX/Linux环境,您可以在手册页中看到drand 48()和srand 48()。如果您不是UNIX/Linux环境,您可以看到C语言的online manuals。原型可以在**/usr/include/stdlib.h**中找到。第一个原型使用在模拟中经常使用的线性同余法。
如果你给srand 48()提供相同的种子,也就是srand 48(2),然后把dran 48()放在一个for循环中,那么每次的序列都是相同的。