如何使OSX的rand()失败光谱测试?

前端之家收集整理的这篇文章主要介绍了如何使OSX的rand()失败光谱测试?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
为了编程类的目的,我试图说明随机生成器通常带有标准C库的缺点,特别是随OSX附带的“坏随机生成器”rand().

我写了一个简单的程序来测试我对光谱测试的理解:

#include <stdio.h>
#include <stdlib.h>

int main() {
  int i;
  int prev = rand();
  int new;

  for (i=0; i<100000; i++) {
    new = rand();
    printf("%d %d\n",prev,new);
    prev = new;
  }
  return 0;
}

但是当我画出结果散点图时,我得到的是:

我会期待一些显示更多结构的东西,就像你所发现的那样.我应该绘制更多维度吗?

UPDATE

按照pjs的建议,我放大了部分地块的数字小于1e7,这里是我发现的:

我发现与pjs完全相同的线条.它们似乎是垂直的,但这是不可能的,因为这意味着某些值被rand()“错过”.当我排序 – 数据这是(我的样本)我看到的:

571 9596797
572 9613604
575 9664025
578 9714446
580 9748060
581 9764867
584 9815288
586 9848902
587 9865709
590 9916130
592 9949744
127774 13971
127775 30778
127780 114813
127781 131620
127782 148427
127783 165234
127785 198848
127787 232462
127788 249269

换句话说,这些点在几乎是垂直的线上.

解决方法

线性同余发生器都受到乔治·马萨利亚(George Marsaglia)确定的问题的影响. “马萨利亚定理”说,k元组(长度为k的向量)将落在有限数量的超平面上.边界是m **(1 / k),其中k是元组的大小,m是发电机模数所用的数字.因此,如果模数为(2 ** 31 – 1),并且您正在查看3的集合,则3-d图将显示点不超过(2 ** 31 – 1)的立方根,或约1290架飞机,从正确的方向看.

所有LCG都受Marsaglia定理.一个“好”的一个在上限或接近上限,一个坏的一个比上限好.这就是光谱测试的有效测量,这就是你在维基百科链接中看到的 – 兰德,来自地狱的液晶显示器,产生了只有15架飞机的三联体.

苹果的碳库生成器使用16807作为其乘数,(2 ** 31-1)作为其模数.随着LCG的到来,这不是真的那么糟糕.因此,你的情节没有显示出与RANDU相同的极限.但是,如果您想要质量好的随机数字,请勿使用LCG.

附录

我已经开始从Apple rand()函数中转出了十亿个数字,但是只打印了两个值都不到200万的值,即图形的左下角.果然,他们落在了一起.您只需要真正放大看到它,因为线密度.

老乔治是一个聪明的小孩!

猜你在找的C&C++相关文章