2010-12-01 6 views
0

ich eine Zufallszahl mit boost Bibliotheken generieren muss, verwende ich diesen Code:C++ Boost-Zufallszahlenerzeugung Problem

boost::mt19937 gen; 
boost::uniform_int<> dist(kUIMinManPort, kUIMaxManPort); 
boost::variate_generator< boost::mt19937&, boost::uniform_int<> > 
var(gen, dist); 
unsigned int value = (unsigned int)var(); 
return boost::lexical_cast<std::string>(value); 

Offensichtlich importiere ich alle notwendigen Bibliotheken. Nun, der Code kompiliert, aber das Problem ist, dass ich die gleichen Zahlen bekomme ....

OK OK ... keine Sorge, ich bin nicht so ein Neuling, wenn über Casual (oder besser Pseudo-casual) Nummer Generation sprechen . Ich weiß, dass wir einen Samen bereitstellen müssen, und dass abhängig von diesem Samen eine Folge von Pseudo-Pseudo-Zahlen bereitgestellt wird.

So dies mein Code wird:

boost::mt19937 gen(static_cast<unsigned int>(std::time(0))); 
boost::uniform_int<> dist(kUIMinManPort, kUIMaxManPort); 
boost::variate_generator< boost::mt19937&, boost::uniform_int<> > 
var(gen, dist); 
unsigned int value = (unsigned int)var(); 
return boost::lexical_cast<std::string>(value); 

Nun, das Problem ist, dass wir fast die gleiche Zahl erhalten jedes Mal rufe ich diese Funktion (innerhalb eines für Zyklus). Ich vermute, dass der zeitabhängige Startwert, der dem Generierungskern der Boost-Zufallsbibliothek zur Verfügung gestellt wird, während der Zeit eines Zyklus nicht variiert, deshalb bekomme ich jedes Mal, wenn ich einen Zyklus fahre, fast die gleiche Zahl und bekomme eine Zufallszahl. Die Frage ist: Wie löst man dieses Problem auf effiziente Weise? Ich nehme eine bewährte Methode gegeben ist ... Nun, ich bin nicht der einzige, ein solches Problem haben :)

Dank ...

+0

Nach einiger Erfahrung würde ich sagen, boost :: random für zB nicht zu verwenden. normale Abweichungen erzeugen, aber ich hatte nie Probleme mit ihren Mersenne Twister. –

+1

Ah, und die Verwendung von time (0) als Seed bedeutet, dass Sie das Programm nicht mehrmals innerhalb einer Sekunde ausführen. Ich verwende normalerweise etwas wie "time (0) + (long long) getpid() << 32" auf Unix. Es gibt ein Äquivalent für Windows. –

+0

'boost :: random_device' (aka' std :: random_device' in C++ 0x) ist eine bessere Quelle für Seeds als 'std :: time()'. Aber es sollte immer noch nicht bei jeder Iteration einer Schleife aufgerufen werden. – Cubbi

Antwort

4
static boost::mt19937 gen(static_cast<unsigned int>(std::time(0))); 

Die static stellt sicher, dass der Generator nur erstellt wird Einmal. Das Problem ist, dass sich time nicht schnell genug ändert. Wenn Sie Ihre Funktion in der gleichen Millisekunde aufrufen, erhalten Sie genau die gleichen Ergebnisse. Leider ist Ihr Code so schnell, dass Sie ihn in der gleichen Millisekunde aufrufen.

Wenn Sie den Generator statisch machen (oder ein Singleton-Muster oder eine globale Variable ...), wird das Problem gelöst.

+1

tatsächlich Zeit (0) ändert sich nur jede Sekunde! –

+0

Was meinen Sie mit "Den Generator statisch machen (oder ein Singleton-Muster oder eine globale Variable ...)"? – Andry

+2

Oder einfach 'gen' außerhalb der Schleife initialisieren ... –