2014-01-13 18 views
6

Der folgende Code zeigt, wie in C++ 11 zufällig zu verdoppeln. In dieser Lösung jedes Mal, wenn ich dieses Programm ausführen, sind die Ergebnisse gleich - ich weiß nicht warum? Wie kann ich es ändern, um bei jedem Programmstart eine andere Lösung zu erhalten?Zufällige Doppel C++ 11

#include <random> 
int main(int argc, char **argv) 
{ 
    double lower_bound = 0.; 
    double upper_bound = 1.; 
    std::uniform_real_distribution<double> unif(lower_bound, upper_bound); 
    std::default_random_engine re;  
    double a_random_double = unif(re); 
    cout << a_random_double << endl; 
    return 0; 
} 
//compilation: "g++ -std=c++0x program_name.cpp -o program_name" 
+1

Geben Sie ihm einen Startwert. Übrigens ist die Fähigkeit, die gleiche Sequenz von "zufälligen" Werten zu erzeugen, für das Testen sehr gut. –

+0

Es gibt keinen guten Grund, 'default_random_engine' zu ​​verwenden. Es ist im Grunde die "Ich interessiere mich nicht" -Maschine, aber dann warum verwenden Sie es, sagen wir, "mt19937", die hohe Qualität * und * kürzer zu tippen ist. –

+2

@CoryNelson 'default_random_engine' ist die offensichtliche Wahl für jemanden, der nichts über zufällige Engines weiß. Deshalb existiert es. Ein Neuling, der zuerst "" und seine Dutzende von Optionen für Engines und Distributionen betrachtet, wird wahrscheinlich nicht das Niveau der Forschung erreichen, das erforderlich ist, um intelligente Entscheidungen zu treffen, sie wollen nur etwas, das funktioniert. Wir sollten einfach glücklich sein, dass sie 'rand()' nicht benutzen. – Casey

Antwort

5

Sie müssen den Zufallszahlengenerator initiieren, bevor Sie Beispiele generieren. Sie tun dies, wenn Sie die default_random_engine Instanz erstellen. Zum Beispiel:

std::random_device rd; 
std::default_random_engine re(rd()); 

Wenn Sie mehr normativ über den Generator Sie dann sollten Sie verwenden, um anzugeben, anstatt für default_random_engine auf der Bibliothek Implementierer Wahl zu verlassen. Die verfügbaren Optionen sind hier aufgelistet: http://en.cppreference.com/w/cpp/numeric/random#Predefined_random_number_generators

Beachten Sie auch, dass einige Implementierungen keine nicht-deterministische Quelle für random_device verwenden. Wenn Sie mit einer solchen Implementierung konfrontiert werden, müssen Sie eine alternative Quelle für Ihren Seed finden.

+0

'std :: random_device {}()' ist eine gute allgemeine Wahl für einen Startwert: 'std :: default_random_engine re {std :: random_device {}()};' – Casey

+0

Achten Sie auf einen unerwarteten Standardstartwert mit MinGW: http://stackoverflow.com/q/18880654/417197 –

0

Der Motor wurde nicht mit einem Seed initialisiert.

#include <chrono> 
... 
std::default_random_engine re(std::chrono::system_clock::now().time_since_epoch().count()); 
0

Wie andere bemerkt haben, haben Sie dem Generator keinen expliziten Startwert gegeben.

Schauen wir uns an, was passiert. GCC implementiert std::default_random_engine als std::linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>. Wenn Sie std::default_random_engine re; schreiben, rufen Sie den Konstruktor für diese Klasse ohne Argumente auf, der standardmäßig auf einem Startwert von linear_congruential_engine::default_seed = 1u basiert. Wenn Sie also einen anderen Samen als 1 möchten, müssen Sie ihn selbst bereitstellen.

Referenz: http://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a00860.html

2

Sie haben den Zufall Motor mit anfänglichem Samen Wert zu initialisieren.
Eine Option ist std::random_device zu verwenden.

#include <iostream> 
#include <random> 

int main() { 
    const double lower_bound = 0; 
    const double upper_bound = 1; 
    std::uniform_real_distribution<double> unif(lower_bound, upper_bound); 

    std::random_device rand_dev;   // Use random_device to get a random seed. 

    std::mt19937 rand_engine(rand_dev()); // mt19937 is a good pseudo-random number 
              // generator. 

    double x = unif(rand_engine); 
    std::cout << x << std::endl; 
} 

Sie können eine große Präsentation online frei verfügbar zu sehen: "rand() Considered Harmful" (von GoingNative 2013 C++ event).