zoukankan      html  css  js  c++  java
  • JS随机数生成算法

    ------------------------------------------

    知乎上边淘到的知识,又学到了~

    http://www.zhihu.com/question/22818104

    ------------------------------------------

    见到这个随机数生成算法好几次了,乍看有点鸡肋本来用Math.random()就可以的事。想不清楚为什么他要用9301,49297,233280这三个数字?其中有道理吗?还是仅是随意选的三个数?但是这个组合貌似流传很广。好多小网站源码里都见到过。

    function rnd( seed ){
        seed = ( seed * 9301 + 49297 ) % 233280; //为何使用这三个数?
        return seed / ( 233280.0 );
    };
    
    function rand(number){
        today = new Date(); 
        seed = today.getTime();
        return Math.ceil( rnd( seed ) * number );
    };
    
    myNum=(rand(5)); 

    Google了一下这3个数字,一些说法也是人云亦云没有找到合理的解释。
    例如:Generate Repeatable Random Numbers (in JS)

    You may ask: Why ‘(seed * 9301 + 49297) % 233280‘ ?!
    The answer is both simple&complicated: The combination of 9301, 49297 and 233280 provide a very even distributed set of “random” numbers. Please don’t ask WHY – that’s the complicated part, some very smart people figured out those numbers quite some time ago, and I also cannot tell you how they did it.

    很聪明的前人算出来的?。。。

    =============================================================
    又找到一个页面 ict.griffith.edu.au/ant 好像有列举,但是没能看懂,ACM之类的。。,有人能解释下不?
    Simple (bad) Psuedo Random Number Generator (Sic)
    The low bit typically just toggles between calls.
    
    random() {
       seed = ( seed * mulitiplier + increment ) % modulus;
       return seed;
    }
    
    Table of Good values
       Multiplier    Increment     Modulus
          25173         13849        65536
           9301         49297       233280

    =+=+=+=+=+=+=+=+=+=+=+=+=
    =+=+=+=+=+=+=+=+=+=+=+=+= 简陋的分割线 =+=+=+=+=+=+=+=+=+=+=+=+==+=+=+=+=+=+=+=+=+=+=+=+=
    here is the answer: 

    很多人认为这是简单的Magic Number,其实这背后有内在的原因,这三个数字并不是随便乱选出来的。

    入门级的选择标准
    这种伪随机数生成器叫做线性同余生成器(LCG, Linear Congruential Generator),几乎所有的运行库提供的rand都是采用的LCG,形如:
    I_{n+1}=aI_n+c (mod m)
    生成的伪随机数序列最大周期m,范围在0到m-1之间。要达到这个最大周期,必须满足
    • c与m互质
    • a - 1可以被m的所有质因数整除
    • 如果m是4的倍数,a - 1也必须是4的倍数
    
    以上三条被称为Hull-Dobell定理。
    作为一个伪随机数生成器,周期不够大是不好意思混的,所以这是要求之一。
    可以看到,a=9301, c = 49297, m = 233280这组参数,以上三条全部满足。

    进阶级的选择标准
    要在伪随机数生成器界混,仅仅入门是不够的。
    从工程的角度来讲,(m-1)a+c的值要(在合理的范围内)足够小,以避免溢出的问题。
    从安全(实用)性的角度来讲,还要满足良好的随机性,这一点可以通过Knunth's Spectral Test来评估(见[2]),要通过2,3,4,5以及6维的Spectral Test才行。Spectral Test考察的就是生成的伪随机数序列在超空间的网格结构(lattice structure),当年IBM的RNADU子程序闹出的乌龙,连3维的Spectral Test就不能通过,上图嘲讽下:
    其中每个点代表三个连续的RANDU生成的伪随机数值,可以看到所有伪随机数分布在了15个二维平面上。

    在这种要求面前,c的值最好:
    • 是质数 (c = 49297就是质数)
    • 接近(frac{1}{2}-frac{1}{6}sqrt{3} )m,(m = 233280时为49297.86460172205)
    
    所以有了这样一些基本的标准,能够选择的参数范围就小了很多,弄个程序跑下Spectral Test,就能得到可选的参数组。

    参考资料:
    [1] nuclear.fis.ucm.es/COMP
    [2] random.mat.sbg.ac.at/te

  • 相关阅读:
    Django 安装
    node上的__dirname和./的区别
    Mysql存储之ORM框架SQLAlchemy(一)
    selenium只打开一个浏览器窗口
    Mysql存储之原生语句操作(pymysql)
    汽车之家反爬
    javascript反混淆之packed混淆(一)
    python近期遇到的一些面试问题(三)
    [转载]关于python字典类型最疯狂的表达方式
    .net爬虫了解一下
  • 原文地址:https://www.cnblogs.com/yangtze736-2013-3-6/p/3563954.html
Copyright © 2011-2022 走看看