2017-03-09 4 views
2

Bevor Sie dies als Duplikat markieren (da mir bekannt ist, dass dies viele Male gefragt wurde) habe ich Dutzende von Fragen/Antworten zu StackOverflow und vielen anderen gelesen "Tutorials" und so.C++ 11 Mersenne Twister erzeugt immer den gleichen Wert

Obwohl ich alle mir bekannten Empfehlungen befolge, erzeugt mein Code jedes Mal, wenn ich ihn ausführe, die gleiche "zufällige" Nummer. Es sieht für mich nicht so aus, als würde ich etwas anderes machen als das, was ich sein sollte. Warum funktioniert das nicht?

#include <random> 
#include <iostream> 
using namespace std; 

random_device rd;  // used to initialise (seed) engine 
mt19937 mt(rd()); // random-number engine used (Mersenne-Twister in this case) 
uniform_int_distribution<int> dist(1, 4); // guaranteed unbiased 

Später im Code/innerhalb einer Funktion:

for (it : vec_one) { 
    int rand_int = dist(mt); // Generate Random Number 
    switch (rand_int) 
    { 
    case 1: 
     cout << "One!" << endl; 
    case 2: 
     cout << "Two!" << endl; 
    case 3: 
     cout << "Three!" << endl; 
    case 4: 
     cout << "Four!" << endl; 
    default: 
     break; 
    } 
} 

Antwort von Kommentaren Fehlende Pausen in der switch-Anweisung. Es war wirklich so einfach. Generator funktioniert gut. Ich habe vergessen, sie in meinen übermüdeten Zustand zu bringen und fühle mich ziemlich dumm. Jedoch ... Die Anzahl der Kommentare und Antworten, die über dieses Problem hinausgehen, verdeutlichen, wie einfach es ist. Ich fühle mich etwas weniger dumm jetzt ...

+1

Werke für mich ganz gut, siehe [hier] (http://coliru.stacked-crooked.com/a/61540450cafd9f1b) für ein anschauliches Beispiel, nicht sicher, was du tust. Kannst du nur ein kleines kompilierbares Beispiel veröffentlichen? Übrigens, du hast keine 'Break's' in den' case' Anweisungen, also wirst du durch die Case Switches fallen und du wirst mit 'One! Enden. Zwei! Drei! Vier! Als Display. – vsoftco

+0

Sind Sie sicher, dass dies mit MSVC und nicht mit MinGW oder etwas ist? Zuletzt wusste ich, libstdC++ Windows-Implementierungen haben 'random_device' nicht deterministisch gemacht (was aus Sicht des Standards immer noch vollkommen legal ist). – chris

+1

Was ist das Ergebnis von 'cout << rd.entropy()' auf Ihrem System? Siehe auch http://www.cplusplus.com/reference/random/random_device/. Wenn Ihr System keinen tatsächlichen nicht-deterministischen Zufallszahlengenerator hat, würden Sie nicht erwarten, jedes Mal eine andere Sequenz zu sehen (und "entropy()" wird theoretisch 0 zurückgeben) und sollte den Konstruktor 'mt19937' verwenden, der [nimmt stattdessen ein echter Seed] (http://www.cplusplus.com/reference/random/mersenne_twister_engine/mersenne_twister_engine/) (siehe auch das dortige Beispiel). –

Antwort

1

Die Switch-Anweisung fehlt Pausen ...
Der folgende Code macht den Trick.

for (it : vec_one) { 
    int rand_int = dist(mt); // Generate Random Number 
    switch (rand_int) 
    { 
     case 1: 
      std::cout << "One!" << std::endl; 
      break; 
     case 2: 
      std::cout<< "Two!" << std::endl; 
      break; 
     case 3: 
      std::cout<< "Three!" << std::endl; 
      break; 
     case 4: 
      std::cout<< "Four!" << std::endl; 
      break; 
     default: 
      break; 
     } 
    } 
+1

Weg, um das Problem zu durchschauen. –

5

Technisch ist dies ein gültiges Verhalten. Von cppreference: Wenn eine nicht-determinisQuelle zur Verfügung (beispielsweise ein Hardware-Gerät) nicht an die Umsetzung

std::random_device kann hinsichtlich einer Implementierung definierte Pseudo-Zufallszahlen-Engine implementiert werden. In diesem Fall kann jedes Objekt std::random_device die gleiche Nummernfolge erzeugen.

Wenn Sie ein Zitat aus dem Standard bevorzugen, dann ist es an [rand.device]/2:

Wenn Implementierung Einschränkungen nicht-deterministische Zufallszahl verhindern zu erzeugen, kann die Implementierung einen Zufallszahl-Motor verwenden .

random_device::entropy() soll für die Überprüfung dieser verwendet werden, aber leider implementiert, es ist nicht richtig in den meisten Bibliotheken, wie die doc-Staaten verbunden sind (und ich kann es für GCC 6.3, 3.9 und Clang MSVC 2015 bestätigen).

Verwandte Themen