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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM