2012-08-13 40 views
18

我試圖從python的random.random()在不同的系統上安裝不同的python3版本來重現隨機序列。爲什麼在Python版本之間播種隨機生成器不穩定?

這應該是很容易的documentation says

大多數的隨機模塊的算法和直播功能 受到不同的Python版本中的更改,但有兩個方面 保證不變:

  • 如果添加新的播種方法,則會提供向後兼容的播種機 。
  • 當兼容播種機被賦予相同的 種子時,生成器的random()方法將繼續到 產生相同的序列。

因此,我希望下面的代碼總是打印相同的10個號碼,不管具體python3版本:

import sys 
print(sys.version) 

from random import seed, random 

seed(str(1)) 
for i in range(10): 
    print(random()) 

然而,測試它在兩臺不同的機器:

3.2.3 (default, May 3 2012, 15:51:42) 
[GCC 4.6.3] 
0.4782479962566343 
0.044242767098090496 
0.11703586901195051 
0.8566892547933538 
0.2926790185279551 
0.0067328440779825804 
0.0013279506360178717 
0.22167546902173108 
0.9864945747444945 
0.5157002525757287 

and

3.1.2 (release31-maint, Dec 9 2011, 20:59:40) 
[GCC 4.4.5] 
0.0698436845523 
0.27772471476 
0.833036057868 
0.35569897036 
0.36366158783 
0.722487971761 
0.963133581734 
0.263723867191 
0.451002768569 
0.0998765577881 

給出不同的結果。

這是爲什麼?而有沒有什麼辦法,使這項工作

+1

爲它的價值,在2.7上運行您的代碼段會產生完全不同的一套比任何您發佈的兩個數字。 – 2012-08-13 07:20:05

+3

它聲明*將提供向後兼容播種機*不是現有方法將向後兼容。 – borrible 2012-08-13 07:25:03

回答

15

我一直在尋找通過What's New in Python 3.2(因爲這個問題),我發現(即獲得相同的隨機序列兩次?):

的random.seed ()函數和方法現在帶有sha512散列函數的鹽串種子。要訪問先前版本的種子以重現Python 3.1序列,請將version參數設置爲1,random.seed(s,version = 1)。

它似乎是一個突破性變化(從3.1到3.2)與向後兼容性選項。

(如borrible指出,由於兼容播種機提供的文檔的合同還沒有受到侵犯。)

+0

謝謝,這一定是問題所在。我必須說,版本參數在3.1中不存在:( – 2012-08-13 07:29:37

+1

這適用於你使用字符串種子的情況。與OP不同,我使用ints播種我的隨機數生成器,並看到不同的結果。順便說一句,getstate()方法返回相同的內部狀態,所以它不是修改的播種位,它實際上是隨機的nuumber生成。 – 2013-02-08 07:36:18

+3

哦,實際上我看到random.random()產生相同的序列 - 它是random.shuffle( )和random.randrange(),它們在Python 3.1和3.2上產生不同的結果,即使給定相同的種子。:-( – 2013-02-08 07:38:53

4

seed文檔說,他們使用的哈希函數將字符串轉換爲有效的輸入種子。當我測試了Python2.X的各種版本(目前沒有安裝3個版本)時,某些版本給出了hash(str(1))的不同值。請注意,針對種子的文檔說,不管版本如何,它們都使用hash值作爲字符串。你可能想傳遞一個int(除了@pst關於使用向後兼容版本的種子的觀點)。

random module docs中摘錄3。2:

如果x是一個int,則直接使用它。

對於版本2(默認值),str,bytes或bytearray對象將 轉換爲int並使用其所有位。使用版本1時,將使用x的 hash()。

(X這裏是種子初始化)