2014-07-16 46 views
5

嘗試的問題:兩個骰子中的一個骰子比第三個骰子具有更高的值的概率。Python隨機不像

問題:由於某些原因,當我使用從蟒的random模塊(特別是樣品的方法),我結束了從噹噹我使用numpy的不同的(和不正確的)的結果。我已將結果列入底部。重複執行代碼會得到類似的結果。任何想法,爲什麼random.sample方法和numpy.random.random_integers有不同的結果,即使它們具有相同的功能?

import numpy as np                
import random                 


random_list = []                 
numpy_list = []                 
n= 500                   
np_wins = 0                  
rand_wins = 0                 
for i in range(n):                
    rolls = random.sample(range(1,7), 3)           
    rand_wins += any(rolls[0] < roll for roll in rolls)       

    rolls = np.random.random_integers(1, 6, 3)         
    np_wins += any(rolls[0] < roll for roll in rolls)       


print "numpy : {}".format(np_wins/(n * 1.0))          
print "random : {}".format(rand_wins/(n * 1.0))   

結果:這裏

 

Press ENTER or type command to continue 
numpy : 0.586 
random : 0.688 
 

回答

4

觀察到的差異的原因是random.sample樣品沒有更換(請參閱here),而numpy.random.random_integers樣品與替換。

2

兩個問題(一個小的,一個顯著):

  1. 你的樣本量很小,以得到一個好的結果。如果我只做500卷,結果在0.55和0.62之間。非常準確。

  2. random.sample選取3個項目而不將它們從給定的順序放回。所以你不會做三次擲骰子,你會從範圍內挑選三個不同的數字[1,6]。事實上,如果我這樣做了,那麼概率是67%,而對於你所說的問題,你認爲它是58%左右,正如你觀察到的那樣。

PowerShell的測試代碼我使用:

原始問題陳述:

(1..500 | %{ 
    $r = 0..2 | %{ Get-Random -min 1 -max 7 } 
    !!($r|?{$r[0] -lt $_}) 
} | measure -ave).Average 

你有缺陷的方法:

(1..500 | %{ 
    $r = 1..6 | Get-Random 3 
    !!($r|?{$r[0] -lt $_}) 
} | measure -ave).Average 

那些獲得你所觀察到的相同的結果差異。

+0

對問題的解釋很好,+1用於識別相對較小的樣本節。值得注意的是,numpy.random.random_integers()會產生正確的結果,解決問題#2,同時增加樣本到n = 100000將緩解問題#1。 –

3

random.sample()防止雙重值。這就像繪製數字而不替換它們一樣,因此像[ 1, 1, 1 ]這樣的結果將不會發生。

np.random.random_integers()另一方面是你真正想要的,如果你模擬三個模具輥。

您可以用[ random.randint(1, 6) for _ in range(3) ]等來代替random.sample(),以達到相同的結果。