Boost.Random - immer die gleiche Zufallszahl
-
Du benutzt so immer den gleichen seed. Selbst, wenn Du einen seed setzt (z.B. mittels
std::time), dann setzt Du, wenn die Deine Funktion mehrfach sehr schnell aufrufst vielfach den gleichen seed, weilstd::timesich nicht schnell genug ändert.
Mögliche Lösung: Zum Beispiel einen Funktor benutzen, welche den Generator im Ctor einmal initialisiert:class Dice { public: Dice() : engine(std::time(0)){}; int operator()(int minIncluded, int maxIncluded) { return boost::uniform_int<int>(minIncluded, maxIncluded)(engine); } private: boost::mt19937 engine; }; int main() { Dice dice; std::cout << dice(10, 20) << '\n'; std::cout << dice(10, 20) << '\n'; std::cout << dice(20, 30) << '\n'; }
-
Danke, genau in den schnell aufeinander folgenden Funktionsaufrufen liegt denke ich der Haken. Mal schauen ob es nun klappt ...
-
boostwirdüberbewertet schrieb:
Was macht boost::random so besonders als ctime-random?
Warum ist nachts kälter als draußen?
-
boostwirdüberbewertet schrieb:
Was macht boost::random so besonders als ctime-random?
Eine Meta-Compiletime-Template-Random-Generation. :p
-
@boostwirdüberbewertet: Zumindest hat man sich von Boost inspirieren lassen. In C++0x wird es einen Header <random> geben, der Nach Abbild von Boost Zufallszahlengeneratoren anbieten wird.
Warum ist das gut? Zum einen arbeitet man dann nicht mehr mit einem globalen Zustand, wie es std::rand tut (böse!) und zum Anderen bietet die Bibliothek Zufallsgeneratoren mit einer höheren "statistischen Qualität".
-
Danke krümelkacker, deine Antworten sind immer sehr verständlich.
Shlo schneid dir eine Scheibe von ihm ab !
-
Also klappt immer noch nicht, dazu verwundet es mich, dass der Test in meiner main-Methode funktioniert, aber der geplante Ablauf über die Hilfsklasse und Hilfsmethoden nicht - wo ist der Haken?
main.cpp - main():
... cout << "RANDOM-Test:\n"; Dice dice; for (int i = 0; i < 6; i++) { cout << dice(0, 6) << endl; }... hier geht, Ausgabe liefert unterschiedliche Integers.
main.cpp - Hilfsmethoden aus main() gerufen:
int getRandomInteger( int minIncluded, int maxIncluded ) { Dice dice; int ranInt = dice( minIncluded, maxIncluded ); return ranInt; } vector<string> randomizeSequenceStrings( vector<string> seqList ) { vector<string> ranSeqList; int j = 0; for ( int d = 0; d < seqList.size(); d++ ) { string curSeqString = seqList.at( d ); int stringSize = curSeqString.size(); string randomizedSeqString( curSeqString ); for ( int i = 0; i < stringSize; i++ ) { int firstRandom = getRandomInteger( 0, (stringSize-1) ); string sub1 = curSeqString.substr( 0, firstRandom ); string sub2 = curSeqString.substr( firstRandom ); randomizedSeqString = sub2; randomizedSeqString += sub1; cout << "... ... for-innnen Lauf ("; cout << i; cout << "), nimm Zufallszahl ("; cout << firstRandom; cout << "), zerteile String in sub1 ("; cout << sub1; cout << ") und sub2 ("; cout << sub2; cout << ") und konkateniere die beiden zu randomString ( "; cout << randomizedSeqString; cout << ");\n"; } ranSeqList.push_back( randomizedSeqString ); j++; } return ranSeqList; }... hier kommt immer der gleiche Integer aus getRandomInteger() in randomizeSequenceStrings() an ?!
-
Wieder genau das gleiche Problem wie vorher: Dadurch, dass Du die Dice-Klasse lokal in der getRandomInteger-Funktion aufrufst, wird jedes mal ein neues Objekt angelegt und dabei der Seed bei jedem Aufruf neu gesetzt. Und der gesetzte Seed bleibt über mehrere Aufrufe hinweg gleich, weil std::time dem gleichen Wert liefert. Du darfst den Seed nicht ständig neu setzen, sondern nur einfall am Anfang!
-
Okay, also sollte ich den Dice per Referenz in die Methoden reichen und es sollte klappen ... mal schauen ...
-
Okay, nun habe ich es so gemacht, es scheint zu klappen: die dice-Instanz erzeuge ich als globale Variable und lasse diese dann von der getRandomInteger-Methode verwenden - aber gedanklich durchdrungen habe ich das noch nicht, warum das plötzlich klappt und vorher eben nicht.
-
Die Seed ist nur für die Initalisierung der Zahlenreihnfolge von Nöten.
Die Random-Funktion gibt dir eine Zahlenfolge, Gib mir die erste Zahl vom Seed (beim ersten Aufrufe), Gib mir die zweite Zahl vom Seed (beim zweiten Aufrufe),...
Bei deinen Aufrufen ist der Seed aber identisch, weil der Aufruf so schnell geht, dass kein zeitunterschied festzustellen ist. Deswegen wird immer der selbe Wert ausgespuckt.