2013-08-12 13 views
9

Sto provando a tradurre qualche codice Python in C++. Ciò che fa il codice è eseguire una simulazione di monte carlo. Ho pensato che i risultati di Python e C++ potrebbero essere molto vicini, ma sembra che sia successo qualcosa di divertente.Differenza tra generazione di numeri casuali C++ e Python

Ecco quello che faccio in Python:

self.__length = 100 
self.__monte_carlo_array=np.random.uniform(0.0, 1.0, self.__length) 

Ecco quello che faccio in C++:

int length = 100; 
std::random_device rd; 
std::mt19937_64 mt(rd()); 
std::uniform_real_distribution<double> distribution(0, 1); 

for(int i = 0; i < length; i++) 
{ 
    double d = distribution(mt); 
    monte_carlo_array[i] = d; 
} 

ho corse generazione di numeri sopra casuali volte 100x5 sia in Python e C++ e quindi fai simulazione di monte carlo con questi numeri casuali.

Nella simulazione monte carlo, ho impostato la soglia su 0,5, quindi posso facilmente verificare se i risultati sono distribuiti uniformemente.

Ecco un progetto concettuale che cosa simulazione Monte Carlo fa:

for(i = 0; i < length; i++) 
{ 
    if(monte_carlo_array[i] > threshold) // threshold = 0.5 
     monte_carlo_output[i] = 1; 
    else 
     monte_carlo_output[i] = 0; 
} 

Dal momento che la lunghezza della matrice Monte Carlo è 120, mi aspetto di vedere 60 1 s sia in Python e C++. Ho calcolato il numero medio di 1 s e ho scoperto che, sebbene il numero medio in C++ e Python sia intorno a 60, ma la tendenza è altamente correlata. Inoltre, il numero medio in Python è sempre più alto rispetto a C++.

distribution chart Posso sapere se questo è perché ho fatto qualcosa di sbagliato, o semplicemente perché la differenza tra i meccanismi di generazione casuale in C++ e Python?

[modifica] prega di notare che il RNG in Python è anche il Mersenne Twister 19937.

+1

Generatori di numeri casuali diversi forniscono diversi set di numeri casuali. Mi sarei aspettato che se lo avessi eseguito più volte (come centinaia di volte), avresti una differenza meno ovvia. –

+2

Questo è davvero quello che vedi con il codice che mostri? Ci devono essere altri input, altrimenti non ci sarebbe alcuna correlazione tra i codici! Sospetto che il bug sia altrove ... –

+0

Questi risultati sono stati manipolati ... –

risposta

5

Ho scritto questo in base al codice scritto:

import numpy as np 

length = 1000 
monte_carlo_array=np.random.uniform(0.0, 1.0, length) 
# print monte_carlo_array 
threshold = 0.5 
above = 0 

for i in range (0,length): 
    if monte_carlo_array[i] > threshold: 
     above+=1 
print above 

e questo in C++:

#include <random> 
#include <iostream> 

int main() 
{ 
    const int length = 1000; 
    std::random_device rd; 
    std::mt19937_64 mt(rd()); 
    std::uniform_real_distribution<double> distribution(0, 1); 
    double threshold = 0.5; 
    double monte_carlo_array[length]; 

    for(int i = 0; i < length; i++) 
    { 
     double d = distribution(mt); 
     monte_carlo_array[i] = d; 
    } 
    int above = 0; 

    for(int i = 0; i < length; i++) 
    { 
     if (monte_carlo_array[i] > threshold) 
     { 
      above++; 
     } 
    } 
    std::cout << above << std::endl; 
} 

Cinque corse ciascuna dà:

Python: 
480 
507 
485 
515 
506 
average: 
498.6 

C++: 
499 
484 
531 
509 
509 
average 
506.4 

Quindi semmai trovo che C++ sia superiore a python. Ma penso che sia più un caso di "numeri casuali non distribuiti uniformemente con un piccolo numero di campioni".

ho cambiato la lunghezza a 100000 invece, e ancora i risultati variano su e giù intorno a 50k:

Python: 

50235 
49752 
50215 
49717 
49974 

Average: 
49978.6 

C++: 

50085 
50018 
49993 
49779 
49966 

Average: 
49968.2 

In sintesi, non credo che sia alcuna differenza enorme tra le implementazioni di numeri casuali in C++ e Python quando si tratta di "quanto uniforme è intorno a 0,5". Ma non ho studiato molto le statistiche (ed è stato molti anni fa).

+0

Ciao, Mats. Grazie mille per la tua risposta. Sono completamente d'accordo con te sul fatto che con un grande campione, non ci potrebbe essere alcuna differenza enorme. Tuttavia, in pratica, non creo nemmeno un array lungo 1000 ma un 120. Pertanto è ragionevole notare alcune differenze. E in pratica, l'output di monte carlo viene moltiplicato per un numero casuale con un intervallo, e l'intervallo è lo stesso sia per Python che per C++. int importo = 0; per (i = 0; i <120; i ++) importo + = monte_carlo_output * random_number; Tuttavia, ciò che mi dà conforto è che Python batte sempre C++ in termini di valori. – ChangeMyName

+0

Probabilmente è perché hai eseguito solo 5 volte. Ho riscritto il codice di cui sopra per eseguire corse di 120, e sebbene la variazione sia maggiore, il risultato è comunque che ottengo circa 60 "sopra 0,5" - ma varia. Ho appena fatto 10000 esecuzioni in python, e varia da 40 a 79 dei numeri superiori a 0,5. In C++, su un singolo esempio, ho ottenuto da 42 a 80. In altre parole, se stai facendo la stessa cosa in C++ e in Python, dovresti ottenere lo stesso risultato (e hai gli stessi generatori di numeri casuali che ho - che è ovviamente del tutto possibile se si esegue, ad esempio, su una macchina Windows che non si esegue) –

0

Quando non si è sicuri in numeri casuali, è sufficiente generare una quantità enorme di numeri casuali utilizzando un servizio come Random ORG. Dopo questo rifornimento questo numeri come matrice in entrambe le implementazioni (C++ e Python). In questo modo sarete sicuri che entrambi i programmi utilizzano lo stesso set di numeri casuali e sarete in grado di confermare che il resto del codice è OK.

Problemi correlati