2016-07-22 8 views
11

Ich habe eine einfache Code-Beispiel:Warum GCC und MSVC std :: normal_distribution sind anders?

#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; 
} 

Was ich auf gcc und msvc kompilieren. Ich bekomme diferent Ergebnisse auf std Code! ( enter image description here

Warum GCC und MSVC std::normal_distribution Ergebnisse sind diferent für den gleichen Samen und Generator, und vor allem, wie man Kraft ihnen gleich sein?

+13

Faszinierend. Ich hätte erwartet, dass sie 100% verschiedene oder 100% identische Zahlen haben. Die Tatsache, dass sie gleich sind, aber neu arrangiert sind, macht mir einen Strich durch die Rechnung. –

+2

Und 'uniform_real_distribution' Ergebnisse sind wie erwartet gleich! – DuckQueen

+3

@MooingDuck: Der Standardalgorithmus erzeugt hier zwei Werte für jede Iteration. Es sieht so aus, als ob sie beide die gleiche Implementierung des Algorithmus verwenden, sich aber unterscheiden, welcher der beiden Werte zurückgegeben wird und welcher zwischengespeichert wird. – Hurkyl

Antwort

6

Es ist problematisch, aber der Standard spezifiziert leider nicht im Detail, welcher Algorithmus zu verwenden ist, wenn (viele) zufällig verteilte Zahlen konstruiert werden, und es gibt mehrere gültige Alternativen mit unterschiedlichen Vorteilen.

26.6.8.5 Normale Verteilungen [ Rand. dist.norm] 26.6.8.5.1 Klasse template normal_distribution [rand.dist.norm.normal]

A normal_distribution Zufallszahlenverteilung erzeugt Zufallszahlen x verteilt entsprechend der Wahrscheinlichkeitsdichtefunktion

enter image description here

Parameter & mgr; und auch als diese Verteilung der Mittelwert und Standardabweichung bekannt.

Der häufigste Algorithmus für normalverteilte Zahlen zu erzeugen ist Box-Muller, aber selbst mit diesem Algorithmus gibt es Optionen und Variationen.

Die Freiheit wird auch ausdrücklich in der Norm erwähnt:

26.6.8 Zufallszahlenverteilung Klassenvorlagen [rand.dist] . . .

3 Die Algorithmen zum Erstellen jeder der angegebenen Verteilungen sind Implementierung definiert.

eine GOTO-Optionen hierfür ist boost random

By the way, wie @Hurkyl weist darauf hin: Es scheint, dass die beiden Implementierungen tatsächlich die gleichen sind: Zum Beispiel Box-muller Wertepaare erzeugt, von denen man wird zurückgegeben und einmal zwischengespeichert wird. Die beiden Implementationen unterscheiden sich nur in dem von den Werten zurückgeführt wird.

Ferner kann die Zufallszahl Motoren vollständig angegeben werden und wird die gleiche Sequenz zwischen Implementierungen geben, aber Pflege benötigt, da die verschiedenen Verteilungen genommen werden können auch unterschiedliche Mengen an Zufallsdaten, um zu konsumieren produzieren ihre Ergebnisse, die die Motoren nicht mehr synchron setzen.

+0

Ich biete ['minstd_rand0'] (http://www.cplusplus.com/reference/random/minstd_rand0/) Generator dazu ... – DuckQueen

+0

Nach Hurkykl Punkte, ist es möglich, MSVC zu seed oder GCC, damit sie dieselben Ergebnisse liefern? – DuckQueen

+0

@DuckQueen. Nein, aber Sie könnten einen Wrapper erstellen, der die zurückgegebenen Zahlenpaare vertauscht. –

7

Im Gegensatz zu den PRN-Generatoren durch den Standard definiert, der die gleiche Leistung für den gleichen Samen des Standard nicht hält dieses Mandat für distrobutions produzieren muß. Aus [rand.dist.allgemein]/3

Die Algorithmen zum Erzeugen der einzelnen angegebenen Verteilungen sind implementierungsdefiniert.

Also in diesem Fall, auch wenn die Verteilung eine Dichtefunktion in Form von

enter image description here

haben muss, wie die Umsetzung, dass tut, ist zu ihnen.

Die einzige Möglichkeit, eine portable Distribution zu erhalten, wäre, eine selbst zu schreiben oder eine Drittanbieterbibliothek zu verwenden.

Verwandte Themen