Ein wenig kommt doch noch zum Thema <random> und C++0x
Es wurden ein paar Neuerungen bzgl. des Zufallsgenerators eingebaut. Man kann nun unter verschiedenen Generatoren wählen. eine Liste der Zufallsgeneratoren ist
hier aufgelistet.
Die ebend angesprochene Chrono Bibliothek soll im folgenden verwendet werden um den mt19937_64 (64bit) zu initialisieren. Im Prinzip genauso wie früher mittels time(NULL) nur halt "moderner" ...
Ich habe jeweils ein kleines Beispielprogramm zu den folgenden Themen geschrieben um das ganze besser zu verdeutlichen:
ChronoSeed.cpp
Code: Alles auswählen
#include <chrono>
#include <iostream>
/*
RandomSeed by Chrono
Liefert einen Ersatz für die Initialisierung des Zufallsgenerators
g++ -std=gnu++0x ChronoSeed.cpp -o ChronoSeed
*/
int main()
{
std::cout << "Zeiten:" << std::endl;
for (int i=0; i < 10; ++i)
std::cout << (std::chrono::high_resolution_clock::now().time_since_epoch().count()) << std::endl;
return 0;
}
Wer
ganzzahlige Zufallszahlen aus einer bestimmten Menge von a bis b benötigt dem sei die Uniform INT Distribution ans Herz gelegt. Mit diesem Code kann man leicht die gewünschten Zufallszahlen generieren. Auch ist es möglich von negativen Ganzzahlen bis hin zu positiven Ganzzahlen eine Menge zu erhalten.
UniformINTDistribution.cpp
Code: Alles auswählen
#include <random>
#include <chrono>
#include <iostream>
/*
Uniform INT distribution
Liefert ganzzahlige Zufahlszahlen aus der Menge [int]min. bis [int]max.
g++ -std=gnu++0x UniformINTDistribution.cpp -o UniformINTDistribution
*/
int main()
{
// Zufallsgenerator initalisieren (64bit Variante)
std::mt19937_64 eng(std::chrono::high_resolution_clock::now().time_since_epoch().count());
int min = 2, max = 8;
std::cout << "Uniform INT Distribution :[" << min << "," << max << "]" << std::endl;
// Bereich festlegen aus der die Zahlen generiert werden sollen
std::uniform_int_distribution<int> uniform_int(min,max);
for (int i=0; i < 10; ++i)
{
for(int j=0; j < 10; ++j)
{
// Zufallszahl aus Bereich ausgeben
std::cout << uniform_int(eng) << " ";
}
std::cout << std::endl;
}
return 0;
}
Das gleiche gibt es auch für
Fließkommazahlen und nennt sich UniformREALDistribution.
UniformREALDistribution.cpp
Code: Alles auswählen
#include <random>
#include <chrono>
#include <iostream>
/*
Uniform REAL distribution
Liefert Fliesskomma Zufahlszahlen aus der Menge [double]min. bis [double]max.
g++ -std=gnu++0x UniformREALDistribution.cpp -o UniformREALDistribution
*/
int main()
{
// Zufallsgenerator initalisieren (64bit Variante)
std::mt19937_64 eng(std::chrono::high_resolution_clock::now().time_since_epoch().count());
double min = 0.1, max = 0.9;
std::cout << "Uniform REAL Distribution :[" << min << "," << max << "]" << std::endl;
// Bereich festlegen aus der die Zahlen generiert werden sollen
std::uniform_real_distribution<double> uniform_real(min,max);
for (int i=0; i < 10; ++i)
{
for(int j=0; j < 10; ++j)
{
std::cout.fill(' ');
std::cout.width(10);
// Zufallszahl aus Bereich ausgeben
std::cout << std::left << uniform_real(eng) << " ";
}
std::cout << std::endl;
}
return 0;
}
Dann haben wir noch die Möglichkeit uns einen zufälligen
dualen Wert ausgeben zu lassen. Hierbei kann die Gewichtung wie die "Münze" fallen soll beeinflusst werden je nach Wunsch. Dabei ist allerdings von größeren Mengen auszugehen, die dann in der Summe die gewünschte Gewichtung haben. Man kann allerdings schon bei kleineren Mengen den Unterschied erkennen.
BernoulliDistribution.cpp
Code: Alles auswählen
#include <random>
#include <chrono>
#include <iostream>
/*
Bernoulli Distribution
Liefert ein dualen Wert ähnlich einem Münzwurf.
g++ -std=gnu++0x BernoulliDistribution.cpp -o BernoulliDistribution
*/
int main()
{
// Zufallsgenerator initalisieren (64bit Variante)
std::mt19937_64 eng(std::chrono::high_resolution_clock::now().time_since_epoch().count());
double p = 0.5;
std::cout << "Bernoulli Distribution :[" << p << "]" << std::endl;
// Gewichtung der mengenmäßigen Verteilung festlegen
// 0.25 = 25[0] / 75[1]
// 0.5 = 50[0] / 50[1]
// 0.75 = 25[0] / 75[1]
std::bernoulli_distribution bernoulli(p);
for (int i=0; i < 10; ++i)
{
for(int j=0; j < 10; ++j)
{
// Münze werfen ...
std::cout << bernoulli(eng) << " ";
}
std::cout << std::endl;
}
return 0;
}
Alle Beispiele sind unter Linux Debian getestet und mit
g++ -std=gnu++0x zu kompilieren.
[
gcc version 4.7.2 (Debian 4.7.2-4)]
Gruß Fisherman