2016-07-22 14 views
11

mam prosty przykładowy kod:Dlaczego GCC i MSVC std :: normal_distribution są różne?

#include <iostream> 
#include <random> 
using namespace std; 
int main() { 
    minstd_rand0 gen(1); 
    uniform_real_distribution<double> dist(0.0, 1.0); 
    for(int i = 0; i < 10; ++i) { 
     cout << "1 " << dist(gen) << endl; 
    } 

    normal_distribution<double> dist2(0.0, 1.0); 
    minstd_rand0 gen2(1); 
    for(int i = 0; i < 10; ++i) { 
     cout << "2 " << dist2(gen2) << endl; 
    } 

    return 0; 
} 

Które skompilować na gcc i msvc. I dostać Diferent wyniki na kodzie std! ( enter image description here

Więc dlaczego GCC i MSVC std::normal_distribution wyniki są zmierzających do tego samego materiału siewnego i generatora, i, co najważniejsze, jak siła im być takie same?

+13

Fascynujące. Spodziewałbym się, że będą miały 100% różne lub w 100% identyczne liczby. To, że są takie same, ale przebudowane, budzi mój umysł. –

+2

Wyniki 'uniform_real_distribution' są zgodne z oczekiwaniami! – DuckQueen

+3

@MooingDuck: Standardowy algorytm tutaj tworzy dwie wartości w każdej iteracji. Wygląda na to, że obaj używają tej samej implementacji algorytmu, ale różnią się, która z tych dwóch wartości jest zwracana, a która jest buforowana. – Hurkyl

Odpowiedz

6

jest to problematyczne, ale średnia niestety nie określa szczegółowo, co algorytm użyć przy konstruowaniu (wielu) z losowo rozmieszczonych liczb, i istnieje kilka ważnych alternatywy z różnych świadczeń.

26.6.8.5 rozkładów normalnych [ skraj. dist.norm] Szablon normal_distribution 26.6.8.5.1 klasy [rand.dist.norm.normal]

Rozkład normal_distribution liczbę losową generuje losowe liczby x rozmieszczone w zależności od funkcji gęstości prawdopodobieństwa

enter image description here

parametry μ i są również znane jako średnia z tego rozkładu i standardowe odchylenie od wartości .

Najczęstszym algorytm generowania liczb o rozkładzie normalnym jest Box-Muller, ale nawet z tego algorytmu są opcje i warianty.

Wolność jest nawet wyraźnie wymienione w normie:

26.6.8 Losowy numer szablony klasy dystrybucja [rand.dist] . . .

3 Algorytmy do tworzenia każdego z określonych rozkładów są zdefiniowane w implementacji .

GoTo opcje to boost random

Nawiasem mówiąc, jak @Hurkyl zaznacza: Wydaje się, że obie implementacje są właściwie takie same: Na przykład box-Muller generuje pary wartości, z których jeden jest zwracany i raz jest buforowany. Te dwie implementacje różnią się tylko wartością zwracanych wartości.

Ponadto, liczba losowa silniki są całkowicie określone i daje taką samą sekwencję między implementacjach, ale opieka musi być wzięty od różnych rozkładów może również zużywają różne ilości losowych danych w celu produkować ich wyniki, co spowoduje zsynchronizowanie silników.

+0

Udostępniam generator ['minstd_rand0'] (http://www.cplusplus.com/reference/random/minstd_rand0/) ... – DuckQueen

+0

Po punktach Hurkyl, możliwe jest zaszczepienie MSVC lub GCC, aby zapewnić te same wyniki? – DuckQueen

+0

@DuckQueen. Nie, ale możesz stworzyć opakowanie, które zamienia zwrócone pary liczb. –

7

W odróżnieniu od generatorów PRN określonych przez normę, które muszą wytwarzać takie same dane wyjściowe dla tego samego materiału siewnego, norma nie zachowuje tego mandatu dla distrobutions. Od [rand.dist.ogólne]/3

Algorytmy do tworzenia każdej z określonych dystrybucji są definiowane przez implementację.

Więc w tym przypadku, mimo że dystrybucja musi mieć funkcję gęstości w postaci

enter image description here

Jak realizacja robi to do nich.

Jedynym sposobem na uzyskanie przenośnej dystrybucji byłoby napisanie go samodzielnie lub skorzystanie z biblioteki innej firmy.

Powiązane problemy