------------------------------------------
知乎上邊淘到的知識,又學到了~
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.
很聰明的前人算出來的?。。。
=============================================================
又找到一個頁面 http://www.ict.griffith.edu.au/anthony/info/C/RandomNumbers 好像有列舉,但是沒能看懂,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,形如:

生成的偽隨機數序列最大周期m,范圍在0到m-1之間。要達到這個最大周期,必須滿足
- c與m互質
- a - 1可以被m的所有質因數整除
- 如果m是4的倍數,a - 1也必須是4的倍數
以上三條被稱為Hull-Dobell定理。
作為一個偽隨機數生成器,周期不夠大是不好意思混的,所以這是要求之一。
可以看到,a=9301, c = 49297, m = 233280這組參數,以上三條全部滿足。
進階級的選擇標准
要在偽隨機數生成器界混,僅僅入門是不夠的。
從工程的角度來講,
的值要(在合理的范圍內)足夠小,以避免溢出的問題。
從安全(實用)性的角度來講,還要滿足良好的隨機性,這一點可以通過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就是質數)
- 接近
,(m = 233280時為49297.86460172205)
所以有了這樣一些基本的標准,能夠選擇的參數范圍就小了很多,弄個程序跑下Spectral Test,就能得到可選的參數組。

參考資料:
[1] http://nuclear.fis.ucm.es/COMP-PHYS/RANDOM/RandomNumbers.pdf
[2] http://random.mat.sbg.ac.at/tests/theory/spectral/