【发布时间】:2011-03-31 01:11:55
【问题描述】:
我非常喜欢能够重复生成同一组伪随机数据,尤其是在调整实验代码时。通过观察我会说rand() 似乎每次都给出相同的数字序列*。
是否保证在同一台机器上/不同机器/不同架构上重复执行?
*显然是同一个种子。
【问题讨论】:
我非常喜欢能够重复生成同一组伪随机数据,尤其是在调整实验代码时。通过观察我会说rand() 似乎每次都给出相同的数字序列*。
是否保证在同一台机器上/不同机器/不同架构上重复执行?
*显然是同一个种子。
【问题讨论】:
是的,给定相同的程序环境。来自 C 标准 §7.20.2.2/2,
srand函数将参数用作新伪随机数序列的种子,这些伪随机数序列将在后续调用rand时返回。 如果srand被调用时使用相同的种子值,则伪随机数序列应重复。 如果在调用srand之前调用rand,则相同序列应在第一次调用srand时生成,种子值为 1。
当然,这假设它使用相同的实现细节(即相同的机器,相同的库在相同的执行周期)。 C 标准不强制规定标准的随机数生成算法,因此,如果您使用不同的 C 标准库运行程序,可能会得到不同的随机数序列。
如果您需要具有给定种子的可移植且有保证的随机数序列,请参阅问题Consistent pseudo-random numbers across platforms。
【讨论】:
rand() 的实现,它可能会在不重建任何东西的情况下采取不同的行动。
srand() 时都将获得相同的序列在一次程序执行期间(“如果 srand 被调用...” 意味着它发生在同一个程序中)。实现在程序启动时选择“主种子”是符合要求的,这会在每次程序运行时扰乱不同的算法。
保证为传递给srand() 的相同种子提供相同的序列 - 但仅在程序的单次执行期间。一般来说,如果一个实现可以选择行为,则没有具体要求该选择在后续执行中保持不变。
在每次程序启动时选择一个“主种子”,并使用它以每次程序启动时不同的方式扰乱伪随机数生成器,这将是符合要求的。
如果您希望获得更多确定性,您应该在程序中实现带有特定参数的 PRNG。
【讨论】:
没有。
C 标准说:
如果 srand 则以相同的方式调用 种子值,序列 伪随机数应为 重复。
但它没有说明伪随机数序列实际上是什么 - 所以它在不同的实现中有所不同。
唯一的保证是rand() 将为给定的种子提供相同的数字序列对于给定的实现。无法保证在不同机器或不同架构之间的顺序是相同的 - 而且几乎可以肯定不会。
【讨论】:
如果您需要使用完全相同的一组伪随机数进行实验,您可以使用srand 生成一长串随机数并将它们写入文件/数据库。然后,编写一个可移植的“随机数生成器”函数,从该文件中按顺序返回值。这样,无论平台、srand 实现或种子值如何,您都可以放心使用相同的输入数据。
【讨论】:
当切换到不同的机器/运行时/无论你可能不走运。 drand48 系列函数还有另一种可能的选择。这些被标准化以在所有机器上使用相同的算法。
【讨论】:
如果您在 UNIX/Linux 环境中,您可以在手册页中看到 drand48() 和 srand48() 如果不是,您可以看到 @987654321 @ 代表 C 语言。 原型可以在 /usr/include/stdlib.h 中找到。 第一个使用模拟中经常使用的线性同余方法。
如果您为 srand48() 提供相同的种子,即 srand48(2),然后将 dran48() 放入 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;
}
【讨论】: