2013-02-25 141 views
4

爲了防止長時間運行的預渲染腳本中的內存損壞,我希望能夠對我的程序說「好吧,呈現前1000步」。然後我可以看看輸出,檢查它等。然後我想說「現在生成步驟1,001到10,000」。保存/恢復PHP的rand狀態()

我的工作幾乎完美。只有一件事我正在努力。

渲染腳本使用rand()向生成的輸出添加熵,srand()在開始時確保它在重新渲染中保持不變。目前我通過計算調用次數rand()來「解決」這個問題,然後在開始實際生成之前多次調用它。問題在於它可能非常緩慢,尤其是當我生成了幾百萬個隨機數時。

是否有任何方法可以確定我需要傳遞給srand()以繼續生成序列的值?這甚至有可能嗎?

如果沒有,是否有任何方法可以找出確切的算法rand()正在使用?我真的很喜歡我從srand(43)得到的地圖,並希望儘可能保留它!


編輯:使用Patashu的答案,這是我想出來的:

function rnd() { 
    static $seed = 42; 
    $seed = $seed*214013+2531011; 
    $mod = pow(2,32); 
    while($seed > $mod) $seed -= $mod; 
    $rs = floor($seed/65536)&0x7fff; 
    return floor(2*$rs/0x8000); 
} 

它依賴於使用花車因爲據我可以告訴尾數的51位足夠容易以完美的精度存儲數字,如果使用位操作符,則整數會被截斷或環繞。

+2

實際'rand'的實現取決於底層操作系統。這個事實可以有[令人驚訝的效果](http://cod.ifies.com/2008/05/php-rand01-on-windows-openssl-rand-on.html)。 – Gumbo 2013-02-25 04:22:23

回答

1

這裏http://cod.ifies.com/2008/05/php-rand01-on-windows-openssl-rand-on.html本頁說明

被警告了PHP的蘭特()的源代碼,這是不是很漂亮,它是依賴於PHP的怪癖和蘭特的OS()實現:)

+0

非常有用的鏈接,因爲它似乎我可以再現這裏使用的實際RNG。編輯我的問題以顯示我正在使用的代碼,它看起來是否適合您? – 2013-02-25 05:06:53

2

這不是直接回答你的問題,但因爲它看起來像你不需要特別「好」隨機數,爲什麼不看看寫自己的僞隨機數發生器?這樣,您可以隨時輕鬆地序列化和反序列化其狀態。

http://en.wikipedia.org/wiki/Random_number_generation#Computational_methods算法的東西,甚至可能會做的伎倆。無論何時開始新的序列,您都可以使用當前時間播種。

+0

這可能是我最好的選擇。我會失去我喜歡的地圖,但我相信我會找到另一張地圖。畢竟只有40億種子可供選擇:p – 2013-02-25 04:23:54

+0

因此,如果我理解正確,我可以使用類似的東西? 'function rnd(){static $ seed = 42; $ seed =(($ seed * 0x43fd43fd + 0xc39ec3)>> 4)&0xffffff;返回$ seed%2;}'得到一個隨機的布爾值? – 2013-02-25 04:49:21

+0

@Kolink當然,對我來說很好。它可能不是*非常「隨意」的,但它不應該比PHP所做的更糟,並且應該適合您的需求。你也可以嘗試一下,看看你得到了什麼樣的發行。如果你想要更好的東西,你可以嘗試實現http://en.wikipedia.org/wiki/Mersenne_twister – 2013-02-25 04:55:25

相關問題