Die Bibliothek Boost.Random bietet zahlreiche Zufallsgeneratoren an, die es Ihnen erlauben zu wählen, auf welche Weise Zufallszahlen erzeugt werden sollen. In C++ konnten über die Funktion std::rand()
aus der Headerdatei cstdlib
auch bisher Zufallszahlen erzeugt werden. In diesem Fall hängt es jedoch von der Implementation der Standardbibliothek ab, auf welche Weise Zufallsfallen generiert werden.
Sie können auf alle Zufallsgeneratoren und sonstigen Klassen und Funktionen der Bibliothek Boost.Random zugreifen, indem Sie die Headerdatei boost/random.hpp
einbinden.
Beachten Sie, dass große Teile der Bibliothek mit C++11 in die Standardbibliothek aufgenommen wurden. Unterstützt Ihre Entwicklungsumgebung C++11, können Sie die folgenden Beispielprogramme zu Boost.Random umschreiben, indem Sie auf die Headerdatei random
und den Namensraum std
zugreifen.
boost::random::mt19937
#include <boost/random.hpp>
#include <iostream>
#include <ctime>
#include <cstdint>
int main()
{
std::time_t now = std::time(0);
boost::random::mt19937 gen{static_cast<std::uint32_t>(now)};
std::cout << gen() << '\n';
}
Im Beispiel 60.1 wird auf den Zufallsgenerator boost::random::mt19937
zugegriffen. Indem der Operator operator()
aufgerufen wird, wird eine Zufallszahl generiert, die auf die Standardausgabe ausgegeben wird.
Die von boost::random::mt19937
generierten Zufallszahlen sind Ganzzahlen. Es hängt vom Zufallsgenerator ab, ob Ganz- oder Kommazahlen erzeugt werden. Alle Zufallsgeneratoren definieren einen Typ result_type
, über den der Typ der Zufallszahlen erhalten werden kann. boost::random::mt19937::result_type
ist auf boost::uint32_t
gesetzt.
Alle Zufallsgeneratoren bieten außerdem zwei Methoden min()
und max()
an. Sie geben die kleinste und größte Zahl zurück, die von einem Zufallsgenerator erzeugt werden kann.
Fast alle von Boost.Random angebotenen Zufallsgeneratoren sind Pseudo-Zufallsgeneratoren. Pseudo-Zufallsgeneratoren erzeugen keine wirklich zufälligen Zahlen. Sie basieren auf Algorithmen, die scheinbar zufällige Zahlen erzeugen. boost::random::mt19937
ist einer der angebotenen Pseudo-Zufallsgeneratoren.
Pseudo-Zufallsgeneratoren müssen typischerweise initialisiert werden. Werden sie mit gleichen Zahlen initialisiert, generieren sie gleiche Zufallszahlen. So wird im Beispiel 60.1 der Rückgabewert von std::time()
an den Konstruktor von boost::random::mt19937
übergeben. Auf diese Weise soll sichergestellt werden, dass ein wiederholter Aufruf des Programms zu unterschiedlichen Zeitpunkten nicht zur Ausgabe der immer gleichen Zufallszahl führt.
Pseudo-Zufallsgeneratoren sind für die meisten Anwendungsfälle gut genug. Auch std::rand()
basiert auf einem Pseudo-Zufallsgenerator, der mit std::srand()
initialisiert werden muss. Boost.Random bietet jedoch auch einen Zufallsgenerator an, der echte Zufallszahlen generieren kann – vorausgesetzt, ein Betriebssystem bietet eine Zufallsquelle an, die echte Zufallszahlen erzeugt.
boost::random::random_device
#include <boost/random/random_device.hpp>
#include <iostream>
int main()
{
boost::random::random_device gen;
std::cout << gen() << '\n';
}
Boost.Random bietet mit boost::random::random_device
einen nicht-deterministischen Zufallsgenerator an. Es handelt sich hierbei um einen Zufallsgenerator, der echte Zufallszahlen erzeugt. Es gibt keinen Algorithmus, der initialisiert werden muss und Zufallszahlen berechnet. Eine Vorhersage von Zufallszahlen ist demnach unmöglich. Nicht-deterministische Zufallsgeneratoren werden zum Beispiel in sicherheitsrelevanten Anwendungen verwendet.
boost::random::random_device
greift zur Generierung von Zufallszahlen auf Betriebssystemfunktionen zu. Wird wie im Beispiel 60.2 der Standardkonstruktor verwendet, verwendet boost::random::random_device
unter Windows den Kryptografiedienstanbieter MS_DEF_PROV und unter Linux den Gerätepfad /dev/urandom
als Zufallsquelle.
Möchten Sie eine andere Zufallsquelle verwenden, greifen Sie auf den Konstruktor von boost::random::random_device
zu, der einen Parameter vom Typ std::string
erwartet. Es hängt vom Betriebssystem ab, wie dieser Parameter interpretiert wird. Unter Windows muss es der Name eines Kryptografiedienstanbieters sein, unter Linux ein Gerätepfad.
Beachten Sie, dass Sie die Headerdatei boost/random/random_device.hpp
einbinden müssen, wenn Sie auf die Klasse boost::random::random_device
zugreifen möchten. Diese Klasse ist nicht über boost/random.hpp
verfügbar.
bernoulli_distribution
#include <boost/random.hpp>
#include <iostream>
#include <ctime>
#include <cstdint>
int main()
{
std::time_t now = std::time(0);
boost::random::mt19937 gen{static_cast<std::uint32_t>(now)};
boost::random::bernoulli_distribution<> dist;
std::cout << dist(gen) << '\n';
}
Im Beispiel 60.3 wird auf den Pseudo-Zufallsgenerator boost::random::mt19937
zugegriffen. Darüber hinaus kommt eine Distribution zum Einsatz. Als Distributionen bezeichnet Boost.Random Klassen, die die Bandbreite der Zufallszahlen eines Zufallsgenerators in eine andere Bandbreite übertragen. Während Zufallsgeneratoren wie boost::random::mt19937
eine eingebaute Unter- und Obergrenze für Zufallszahlen haben, die über min()
und max()
ermittelt werden kann, werden häufig Zufallszahlen innerhalb einer bestimmten Bandbreite benötigt.
Im Beispiel 60.3 soll der Wurf einer Münze simuliert werden. Da eine Münze nur zwei Seiten hat, soll der Zufallsgenerator 0 oder 1 zurückgeben. Eine Distribution, die nur eines von zwei Ergebnissen zurückgibt, ist boost::random::bernoulli_distribution
.
Distributionen werden wie Zufallsgeneratoren verwendet: Sie rufen den Operator operator()
auf, um eine Zufallszahl zu erhalten. Distributionen müssen Sie jedoch als Parameter einen Zufallsgenerator übergeben. Im Beispiel 60.3 verwendet dist den Zufallsgenerator gen, um 0 oder 1 zurückzugeben.
uniform_int_distribution
#include <boost/random.hpp>
#include <iostream>
#include <ctime>
#include <cstdint>
int main()
{
std::time_t now = std::time(0);
boost::random::mt19937 gen{static_cast<std::uint32_t>(now)};
boost::random::uniform_int_distribution<> dist{1, 100};
std::cout << dist(gen) << '\n';
}
Boost.Random bietet zahlreiche Distributionen an. Im Beispiel 60.4 wird eine oft benötigte Distribution vorgestellt: Mit boost::random::uniform_int_distribution
kann die Bandbreite der zu generierenden Zufallszahlen vorgegeben werden. So gibt dist im Beispiel 60.4 eine Zahl zwischen 1 und 100 zurück.
Beachten Sie, dass 1 und 100 ebenfalls gültige Zufallszahlen sind, die von dist zurückgegeben werden können. Distributionen werden mit einschließenden Unter- und Obergrenzen initialisiert.
Neben boost::random::bernoulli_distribution
und boost::random::uniform_int_distribution
können Sie auf zahlreiche weitere Distributionen in Boost.Random zugreifen. Dazu zählen zum Beispiel Distributionen wie boost::random::normal_distribution
oder boost::random::chi_squared_distribution
, wie sie in der Stochastik Verwendung finden.