2014-07-16 26 views
5

Tentativo problema: La probabilità che uno dei due dadi abbia un valore superiore a un terzo dado.Python casuale non funziona come

Problema: Per qualche ragione, quando uso il modulo random pitone (in particolare il metodo di esempio), che finisce con un risultato diverso (e corretto) da quando quando uso NumPy. Ho incluso i risultati in fondo. L'esecuzione ripetuta del codice produce risultati simili. Qualche idea, perché il metodo random.sample e lo numpy.random.random_integers hanno risultati diversi anche se hanno la stessa funzione?

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))   

Risultato:

 

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

risposta

4

Il motivo della differenza osservata è che i campioni random.sample senza sostituzione (vedere here), mentre i campioni numpy.random.random_integers con sostituzione.

2

Due problemi qui (un minore, un significativo):

  1. tua dimensione del campione è molto piccolo per ottenere un buon risultato. Se faccio solo 500 rotoli, ottengo un risultato tra 0,55 e 0,62. Poco preciso.

  2. random.sample seleziona 3 articoli senza reinserirli dalla sequenza indicata. Quindi non stai facendo tre tiri di dado, stai selezionando tre numeri distinti nell'intervallo [1, 6].

    Infatti, se lo faccio, la probabilità è del 67%, mentre per il problema hai affermato che è più del 58% circa, come hai osservato.

codice di prova PowerShell che ho usato:

dichiarazione del problema originale:

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

Il tuo metodo imperfetto:

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

Coloro cedere la stessa differenza risultato si osserva.

+0

Buona spiegazione dei problemi e +1 per identificare la sezione di campionamento relativamente piccola. Vale la pena notare che numpy.random.random_integers() darebbe il risultato corretto, affrontando il problema n. 2, mentre aumentando il campione a n = 100000 si allevierebbe il problema n. 1. –

3

random.sample() impedisce il doppio valore. È come disegnare i numeri senza sostituirli, quindi un risultato come [ 1, 1, 1 ] non si verificherà mai.

np.random.random_integers() d'altra parte è ciò che si vuole realmente se si simulano tre tiri di dado.

È possibile sostituire lo random.sample() in base a come [ random.randint(1, 6) for _ in range(3) ] per ottenere lo stesso risultato.