2013-07-12 53 views
3

我正嘗試在Javacript中創建自定義線性同餘發生器(用於glibc中的一個)。
其規定的性質如下:on wikipedia是:m=2^31a=1103515245,c=12345Javascript中的自定義線性同餘發生器

現在我得到下一個種子值與

x = (1103515245 * x + 12345) % 0x80000000 ; // (the same as &0x7fffffff) 

雖然發電機似乎工作,但如果這些數字是在畫布上進行了測試:

cx = (x & 0x3fffffff) % canvasWidth; // coordinate x (the same for cy) 

他們似乎是可怕的偏見:http://jsfiddle.net/7VmR9/3/show/

有關爲什麼發生這種情況的任何想法?通過選擇不同的模數,視覺測試的結果看起來好多了。

測試的jsfiddle是在這裏:http://jsfiddle.net/7VmR9/3/

更新

最後我固定改造畫布座標作爲此公式中:

var cx = ((x & 0x3fffffff)/0x3fffffff*canvasWidth)|0 

現在像素座標並非如此使用模操作時非常格格不入。
更新小提琴:http://jsfiddle.net/7VmR9/14/

+0

對我來說,它的價值似乎是1?也許它應該是2^31 +1?我做了一個動畫來顯示不同的值。 http://jsfiddle.net/cHbXk/ –

回答

2

對於發電機的公式是(你忘了在第一部分的模數):

current = (multiplier * current * modul + addend) % modulus)/modulus 

我知道你嘗試優化,所以我更新了擺弄這使你可以使用它作爲一個基礎的優化:

http://jsfiddle.net/AbdiasSoftware/7VmR9/12/

+1

嗨肯,你說得對我生成兩個畫布座標不正確。最後我使用了這個轉換:'var cx =((x&0x3fffffff)/ 0x3fffffff * canvasWidth)| 0;'http://jsfiddle.net/7VmR9/14/感謝您的幫助!最好的祝福 – Stano

2

是的,它看起來像你解決它。我做了同樣的事情。

線性同餘發生器的形式是:

 
seed = (seed * factor + offset) % range; 

但是,最重要的是,獲得從它的實際隨機數的時候,下面的不起作用:

random = seed % random_maximum;

這將不起作用,因爲第二模量似乎抵消了發生器的影響。相反,你需要使用:

 
random = floor (seed/range * random_maximum); 

(這將是一個隨機整數;去除floor來電索取隨機浮動。)


最後,我會警告你:在javascript,當使用超過dword限制的數字時,會導致精度損失。因此,LCG的隨機結果可能是隨機的,但它們很可能與實際支持雙字數學的C++或另一種低級語言中實現的相同LCG的結果不匹配。

也由於不精確,LCG的週期非常容易大大降低。因此,例如,您參考的glibc LCG的週期可能是40億次(也就是說,它會在重新開始並重新生成完全相同的一組數字之前生成超過40億個隨機數)。由於這個因素乘以這個因子的數量超過了40億,並且在這個過程中失去了精確度,所以這個js的實現可能只有10億或者更少。