3

出于几个正当的原因,我必须使用 BSD 的 random() 来生成大量随机数,并且由于它的周期很短(如果我没记错的话,~2^69)这些数字的质量很快就会下降我的用例。我可以使用我可以访问的 rng 板,但它非常慢,所以我想我可以做到这一点:从板上取一个数字,用它来播种 random(),使用 random() 来绘制数字并在董事会说有一个新号码可用。该板每秒生成大约 100 个数字,所以我的猜测是 random() 几乎无法循环,并且生成速率很容易满足我每秒数百万个数字的要求。

无论如何,问题是 random() 声称均匀地绘制 0 和 (2^31)-1 之间的数字,但我一直在绘制无数的数字,而且我从未见过 0 或 (2^ 31)-1 到目前为止。也许有一些 1 和 (2^31)-2,但我从未见过极端情况。现在,我知道随机数的问题在于您永远无法确定(参见 Dilbert,Debian),但这似乎非常奇怪。此外,我尝试使用 histc() 函数使用 Octave 分析生成的数据集,最低和最高的 bin 包含中间 bin 数量的一半到四分之三(反过来又是均匀填充的,所以我猜在一些感觉分布是“均匀的”)。

有人可以解释一下吗?

编辑一些代码

板子用三个组件输出这个结构,然后我做了一些结合它们来产生种子的mumbo-jumbo。我没有关于这块板的规格,它是几年前以前的学生拼凑的一块古老的硬件,几乎没有文档,我使用的这个公式是文档中建议的公式之一。STEP 参数告诉我可以使用一个种子绘制多少数字,以便我可以同时优化性能并降低 CPU 使用率。

float n = fabsf(fmod(sqrt(a.s1*a.s1 + a.s2*a.s2 + a.s3*a.s3), 1.0));
unsigned int seed = n * UINT32_MAX;
srandom(seed);

for(int i = 0; i < STEP; i++) {
  long r = random();
  n = (float)r / (UINT32_MAX >> 1);
  [_numbers addObject:[NSNumber numberWithFloat:n]];
}
4

2 回答 2

0

为了延长周期长度,一种方法是运行两个具有不同周期的 RNG,并对它们的输出进行异或运算。一些例子见L'Ecuyer 1988

于 2012-05-28T11:36:49.850 回答
0

你确定吗

void main() {
  while (random() != 0L);
}

无限期挂起?在我的 linux 机器上(Gnu C 库使用与 BSD 相同的线性反馈移位寄存器,尽管使用不同的播种过程)它没有。

根据此参考 ,该算法产生连续零或最长长度的“运行”,n-1其中 n 是移位寄存器的大小。当它的大小为 31 个整数(默认情况)时,我们甚至可以确定最终将连续random()返回 0 高达 30 次(但绝不是 31 次)!当然,我们可能要等几个世纪才能看到它的发生……

于 2012-05-27T22:56:02.733 回答