Das Problem
Ich muss dieselbe (Pseudo-)Zufallszahlenfolge auf verschiedenen Maschinen und Compilern erzeugen. Wenn ich denselben Kernel verwende, scheint die Implementierung von Mersenne Twister (MT) in g++ gut zu funktionieren: Unabhängig davon, ob ich mein Programm auf einer neueren Maschine mit g++ 4.9 oder 4.7 kompiliere, erhalte ich dieselben Zufallszahlen. Aber ich bekomme andere, wenn ich einen älteren Kernel verwende oder wenn ich zum Compiler von Visual Studio wechsle. Das ist ok, denn dafür gibt es keine Garantie mersenne_twister_engine::seed
setzt den internen Zustand über verschiedene Compiler hinweg auf den gleichen.
Was ich schon probiert habe
Ich habe das bei der Bewerbung gelernt operator<<
auf dem Generator erzeugt ein eindeutiges Ergebnis, das verwendet werden kann, um die Generatoren auf anderen Maschinen mit einzustellen operator>>
aber im Falle von mt19937
, scheint es nicht zu funktionieren. Um es deutlich zu machen, auf einem Computer hatte die KI den Code
mt19937 generator1A;
uniform_int_distribution<int> distribution(0, 1000);
cout << "Generating random numbers with seed 1000" << endl;
generator1A.seed(1000);
generator1A(); //to advance the state by one so operator>> will give a longer output; this is not necessary indeed
ofstream test("testseed1000.txt");
test << generator1A << endl;
for (int i = 0; i < 10; ++i)
cout << distribution(generator1A) << endl;
Und es produziert 252, 590, 893, … und eine lange Datei. Ich übertrage die Datei auf die andere Maschine B und führe den folgenden Code aus:
mt19937 generator1B, generator2B;
uniform_int_distribution<int> distribution(0, 1000);
cout << "Generating random numbers with seed 1000, and with operator>>" << endl;
generator2B.seed(1000);
generator2B(); // to advance the state by one here as well
ifstream test("testseed1000.txt");
test >> generator1B;
cout << "************************" << endl;
cout << generator1B << endl;
cout << "************************" << endl;
cout << "With seed\twith operator>>" << endl;
for (int i = 0; i < 10; ++i)
cout << distribution(generator2B) << "\t" << distribution(generator1B) << endl;
Und es produziert
654 205
205 115
115 610
Die Frage
Können Sie Ratschläge geben, wie Sie dieselben (Pseudo-)Zufallszahlen mit mindestens VC++ unter Windows und g++ unter Debian und Ubuntu generieren können? Ich möchte std verwenden, wenn es möglich ist, und ich möchte nicht meine eigene MT-Engine implementieren.
Anmerkungen:
- Millionen von Zufallszahlen zu erstellen und dann einzulesen, ist keine Lösung
- Ich muss MSVS für die Codeentwicklung und Unix-Server für die Simulation verwenden
- andere als MT-Motoren sind ebenfalls willkommen, aber ich bevorzuge MT
Ehrlich gesagt macht es mich ziemlich glücklich zu hören, dass Zufallszahlen nicht in der gleichen Reihenfolge auf verschiedenen Maschinen mit dem gleichen Seed generiert werden.
– AndyG
19. Februar 2015 um 13:43 Uhr
@AndyG: Das sollte es nicht. Der springende Punkt bei einem Seed ist es, eine reproduzierbare Sequenz zu erhalten.
– Mike Seymour
19. Februar 2015 um 13:44 Uhr
@MikeSeymour: Punkt genommen. Ich wäre jedoch nicht überrascht, wenn die Maschinen, an denen OP arbeitet, eine Mischung aus 32- und 64-Bit sind, was IIRC auf PRNG auswirken kann.
– AndyG
19. Februar 2015 um 13:49 Uhr
Kleiner Punkt: Sie haben vergessen zu treten
generator2B
einmal nach der Erstellung. (oder du bist getretengenerator1A
bei Unfall)– Benutzer1084944
19. Februar 2015 um 14:11 Uhr
Wenn Sie wirklich reproduzierbar und portabel sein müssen, verwenden Sie kein PRNG aus der Standardbibliothek – für sich selbst, oder verwenden Sie eine Bibliothek eines Drittanbieters mit Quellcode, wie meine eigene ojrandlib.
– Lee Daniel Crocker
19. Februar 2015 um 19:26 Uhr