c++ - tutorial - visual studio code kompilieren




Warum unterscheiden sich GCC und MSVC std:: normal_distribution? (2)

Es ist problematisch, aber der Standard spezifiziert leider nicht im Detail, welcher Algorithmus zu verwenden ist, wenn (viele) der zufällig verteilten 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 Klassenvorlage normal_distribution [rand.dist.norm.normal]

Eine Normalverteilungs-Zufallszahlenverteilung erzeugt Zufallszahlen x, die gemß der Wahrscheinlichkeitsdichtefunktion verteilt sind

Parameter μ und werden auch als Mittelwert und Standardabweichung dieser Verteilung bezeichnet.

Der gebräuchlichste Algorithmus zum Erzeugen normalverteilter Zahlen ist Box-Muller , aber selbst mit diesem Algorithmus gibt es Optionen und Variationen.

Die Freiheit wird sogar explizit im Standard erwähnt:

26.6.8 Templates für die Verteilung von Zufallszahlen [rand.dist]. . .

3 Die Algorithmen zum Erzeugen jeder der angegebenen Verteilungen sind implementierungsdefiniert.

Ein Goto Optionen dafür ist Boost zufällig

Übrigens, wie @Hurky herausfindet: Es scheint, dass die beiden Implementierungen tatsächlich die gleichen sind: Beispielsweise erzeugt box-muller Paare von Werten, von denen einer zurückgegeben wird und einmal zwischengespeichert wird. Die beiden Implementierungen unterscheiden sich nur darin, welcher der Werte zurückgegeben wird.

Außerdem sind die Zufallszahlen- Engines vollständig spezifiziert und geben die gleiche Sequenz zwischen Implementierungen, aber Vorsicht ist geboten, da die verschiedenen Distributionen auch unterschiedliche Mengen von Zufallsdaten konsumieren können, um ihre Ergebnisse zu produzieren, die die Engines ausschließen der Synchronisierung

Ich habe ein einfaches Codebeispiel:

#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 kompiliere . Ich bekomme verschiedene Ergebnisse für den Std-Code!

Also, warum GCC und MSVC std::normal_distribution Ergebnisse sind für die gleichen Samen und Generator, und vor allem, wie sie dieselben zu erzwingen ?


Im Gegensatz zu den durch den Standard definierten PRN-Generatoren, die dieselbe Ausgabe für denselben Samen produzieren müssen, behält der Standard dieses Mandat für Verteilungsbögen nicht bei. Aus [rand.dist.general] / 3

Die Algorithmen zum Erzeugen jeder der angegebenen Verteilungen sind implementierungsdefiniert.

Also in diesem Fall, obwohl die Verteilung eine Dichtefunktion in Form von haben muss

Wie die Implementierung das macht, ist ihnen überlassen.

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





visual-c++