Namespaces
Variants

Pseudo-random number generation

From cppreference.net

Die Zufallszahlenbibliothek bietet Klassen, die Zufalls- und Pseudozufallszahlen erzeugen. Diese Klassen umfassen:

  • Uniforme Zufallsbitgeneratoren (URBGs), die sowohl Zufallszahlengeneratoren (Engines), welche pseudozufällige Zahlenfolgen mit einer Gleichverteilung erzeugen, als auch echte Zufallszahlengeneratoren (falls verfügbar) umfassen.
  • Zufallszahlenverteilungen (z.B. uniform , normal , oder poisson distributions ), die die Ausgabe von URBGs in verschiedene statistische Verteilungen umwandeln.

URBGs und Verteilungen sind dafür konzipiert, gemeinsam verwendet zu werden, um Zufallswerte zu erzeugen. Alle Zufallszahlengeneratoren können gezielt gesät, serialisiert und deserialisiert werden, um mit wiederholbaren Simulatoren verwendet zu werden.

Inhaltsverzeichnis

Gleichmäßige Zufallsbitgeneratoren

Ein uniform random bit generator ist ein Funktionsobjekt, das vorzeichenlose Ganzzahlwerte zurückgibt, sodass jeder Wert im Bereich der möglichen Ergebnisse (idealiter) eine gleiche Wahrscheinlichkeit hat, zurückgegeben zu werden.

Alle gleichförmigen Zufallsbitgeneratoren erfüllen die UniformRandomBitGenerator Anforderungen. C++20 definiert ebenfalls ein uniform_random_bit_generator Konzept.

Definiert im Header <random>
spezifiziert, dass ein Typ als uniform random bit generator qualifiziert
(Konzept)

Zufallszahlengeneratoren

Eine Zufallszahlen-Engine (häufig abgekürzt als Engine ) ist ein gleichmäßiger Zufallsbitgenerator, der pseudozufällige Zahlen unter Verwendung von Seed-Daten als Entropiequelle erzeugt.

Zu jedem beliebigen Zeitpunkt hat eine Engine e vom Typ E einen Zustand e i für eine nicht-negative Ganzzahl i . Bei der Konstruktion erhält e einen Anfangszustand e 0 , der durch Engine-Parameter und einen initialen Seed (oder Seed-Sequenz) bestimmt wird.

Die folgenden Eigenschaften sind für jeden Maschinentyp E stets definiert:

  • Die Größe des Zustands von E in Vielfachen der Größe von E::result_type (d.h. ( sizeof e i ) / sizeof ( E :: result_type ) ).
  • Der Übergangsalgorithmus TA , durch den e ’s Zustand e i zu seinem Nachfolgezustand e i+1 weiterentwickelt wird (d.h. TA ( e i ) == e i+1 ).
  • Der Generierungsalgorithmus GA , durch den e ’s Zustand auf einen Wert des Typs E::result_type abgebildet wird; das Ergebnis ist eine Pseudozufallszahl.

Eine Pseudo-Zufallszahlenfolge kann durch abwechselnden Aufruf von TA und GA erzeugt werden.

Die Standardbibliothek bietet die Implementierungen von drei verschiedenen Klassen von Pseudo-Zufallszahlengenerierungsalgorithmen als Klassentemplates an, sodass die Algorithmen angepasst werden können. Die Auswahl, welche Engine verwendet werden soll, beinhaltet eine Reihe von Abwägungen:

  • Die Linear Congruential Engine ist mäßig schnell und hat einen sehr geringen Speicherbedarf für den Zustand.
  • Die Mersenne Twister Engine ist langsamer und hat höhere Zustandsspeicheranforderungen, bietet jedoch bei richtiger Parametereinstellung die längste nicht-wiederholende Sequenz mit den besten spektralen Eigenschaften (für eine gegebene Definition von "wünschenswert").
  • Die Subtract With Carry Engine ist sehr schnell, selbst auf Prozessoren ohne erweiterte Arithmetik-Befehlssätze, auf Kosten von größerem Zustandsspeicher und manchmal weniger wünschenswerten spektralen Eigenschaften.
  • Der Philox-Engine ist ein zählerbasierter Zufallszahlengenerator . Er hat einen kleinen Zustand und eine lange Periode (nicht weniger als 2^130) und ist für den Einsatz in Monte-Carlo-Simulationen vorgesehen, die massiv parallele Zufallszahlengenerierung erfordern. Er lässt sich leicht vektorisieren und parallelisieren und ist in GPU-optimierten Bibliotheken implementiert.
(seit C++26)

Keiner dieser Zufallszahlengeneratoren ist kryptografisch sicher . Wie bei jeder sicherheitsrelevanten Operation sollte für diesen Zweck eine Kryptografie-Bibliothek verwendet werden (z.B. OpenSSL RAND_bytes ).

Alle von diesen Templates instanziierten Typen erfüllen die RandomNumberEngine Anforderungen.

Definiert im Header <random>
implementiert den linearen Kongruenzgenerator Algorithmus
(Klassentemplate)
implementiert den Mersenne-Twister Algorithmus
(Klassentemplate)
implementiert einen Subtract-with-Carry ( verzögerten Fibonacci ) Algorithmus
(Klassentemplate)
ein zählerbasierter parallelisierbarer Generator
(Klassentemplate)

Zufallszahlengenerator-Adapter

Zufallszahlen-Engine-Adapter erzeugen Pseudo-Zufallszahlen unter Verwendung einer anderen Zufallszahlen-Engine als Entropiequelle. Sie werden im Allgemeinen verwendet, um die spektralen Eigenschaften der zugrundeliegenden Engine zu verändern.

Definiert im Header <random>
verwirft einen Teil der Ausgabe einer Zufallszahlen-Engine
(Klassentemplate)
packt die Ausgabe einer Zufallszahlen-Engine in Blöcke mit einer bestimmten Anzahl von Bits
(Klassentemplate)
liefert die Ausgabe einer Zufallszahlen-Engine in einer anderen Reihenfolge
(Klassentemplate)

Vordefinierte Zufallszahlengeneratoren

Mehrere spezifische populäre Algorithmen sind vordefiniert.

Definiert im Header <random>
Typ Definition
minstd_rand0 (C++11) std:: linear_congruential_engine < std:: uint_fast32_t ,
16807 , 0 , 2147483647 >

1969 von Lewis, Goodman und Miller entdeckt, 1988 von Park und Miller als "Minimalstandard" übernommen

minstd_rand (C++11)

std:: linear_congruential_engine < std:: uint_fast32_t ,
48271 , 0 , 2147483647 >
Neuerer "Minimum Standard", empfohlen von Park, Miller und Stockmeyer im Jahr 1993

mt19937 (C++11)

std:: mersenne_twister_engine < std:: uint_fast32_t ,
32 , 624 , 397 , 31 ,
0x9908b0df , 11 ,
0xffffffff , 7 ,
0x9d2c5680 , 15 ,
0xefc60000 , 18 , 1812433253 >
32-Bit-Mersenne-Twister von Matsumoto und Nishimura, 1998

mt19937_64 (C++11)

std:: mersenne_twister_engine < std:: uint_fast64_t ,
64 , 312 , 156 , 31 ,
0xb5026f5aa96619e9 , 29 ,
0x5555555555555555 , 17 ,
0x71d67fffeda60000 , 37 ,
0xfff7eee000000000 , 43 ,
6364136223846793005 >
64-Bit-Mersenne-Twister von Matsumoto und Nishimura, 2000

ranlux24_base (C++11) std:: subtract_with_carry_engine < std:: uint_fast32_t , 24 , 10 , 24 >
ranlux48_base (C++11) std:: subtract_with_carry_engine < std:: uint_fast64_t , 48 , 5 , 12 >
ranlux24 (C++11) std:: discard_block_engine < std:: ranlux24_base , 223 , 23 >

24-Bit RANLUX-Generator von Martin Lüscher und Fred James, 1994

ranlux48 (C++11) std:: discard_block_engine < std:: ranlux48_base , 389 , 11 >

48-Bit RANLUX-Generator von Martin Lüscher und Fred James, 1994

knuth_b (C++11) std:: shuffle_order_engine < std:: minstd_rand0 , 256 >
philox4x32 (C++26) std:: philox_engine < std:: uint_fast32_t , 32 , 4 , 10 ,
0xCD9E8D57 , 0x9E3779B9 ,
0xD2511F53 , 0xBB67AE85 >
philox4x64 (C++26) std:: philox_engine < std:: uint_fast64_t , 64 , 4 , 10 ,
0xCA5A826395121157 , 0x9E3779B97F4A7C15 ,
0xD2E7470EE14C6C93 , 0xBB67AE8584CAA73B >
default_random_engine (C++11) ein implementierungsdefinierter RandomNumberEngine Typ

Nicht-deterministische Zufallszahlen

std::random_device ist ein nicht-deterministischer gleichförmiger Zufallsbitgenerator, obwohl Implementierungen es erlaubt ist, std::random_device unter Verwendung eines Pseudozufallszahlengenerators zu implementieren, wenn keine Unterstützung für nicht-deterministische Zufallszahlengenerierung vorhanden ist.

Nicht-deterministischer Zufallszahlengenerator unter Verwendung einer Hardware-Entropiequelle
(Klasse)

Zufallszahlenverteilungen

Eine Zufallszahlenverteilung verarbeitet die Ausgabe eines URBG nach, sodass die resultierende Ausgabe gemäß einer definierten statistischen Wahrscheinlichkeitsdichtefunktion verteilt ist.

Zufallszahlenverteilungen erfüllen die Anforderungen RandomNumberDistribution .

Definiert im Header <random>
Gleichverteilungen
erzeugt gleichmäßig verteilte ganzzahlige Werte über einen Bereich
(Klassentemplate)
erzeugt gleichmäßig verteilte reelle Werte in einem Bereich
(Klassentemplate)
Bernoulli-Verteilungen
erzeugt bool -Werte gemäß einer Bernoulli-Verteilung
(Klasse)
erzeugt ganzzahlige Werte gemäß einer Binomialverteilung
(Klassentemplate)
erzeugt ganzzahlige Werte gemäß einer negativen Binomialverteilung
(Klassentemplate)
erzeugt ganzzahlige Werte gemäß einer geometrischen Verteilung
(Klassentemplate)
Poisson-Verteilungen
erzeugt ganzzahlige Werte gemäß einer Poisson-Verteilung
(Klassentemplate)
erzeugt reale Werte gemäß einer Exponentialverteilung
(Klassentemplate)
erzeugt reelle Werte gemäß einer Gamma-Verteilung
(Klassentemplate)
erzeugt reale Werte gemäß einer Weibull-Verteilung
(Klassentemplate)
erzeugt reale Werte gemäß einer Extremwertverteilung
(Klassentemplate)
Normalverteilungen
erzeugt reelle Werte gemäß einer Standardnormalverteilung (Gaußsche Normalverteilung)
(Klassentemplate)
erzeugt reelle Werte gemäß einer Lognormalverteilung
(Klassentemplate)
erzeugt reelle Werte gemäß einer Chi-Quadrat-Verteilung
(Klassentemplate)
erzeugt reelle Werte gemäß einer Cauchy-Verteilung
(Klassentemplate)
erzeugt reelle Werte gemäß einer Fisher's F-Verteilung
(Klassentemplate)
erzeugt reelle Werte gemäß einer Student's t-distribution
(Klassentemplate)
Stichprobenverteilungen
erzeugt ganzzahlige Werte gemäß einer diskreten Verteilung
(Klassentemplate)
erzeugt reelle Werte, die auf konstanten Teilintervallen verteilt sind
(Klassentemplate)
erzeugt reelle Werte, die auf definierten Teilintervallen verteilt sind
(Klassentemplate)

Dienstprogramme

Definiert im Header <random>
verteilt reelle Werte gegebener Genauigkeit gleichmäßig über [ 0 , 1 )
(Funktionstemplate)
(C++11)
allgemeiner Verzerrungs-eliminierender verwürfelter Seed-Sequenz-Generator
(Klasse)

Zufallszahlenalgorithmen

Definiert im Header <random>
füllt einen Bereich mit Zufallszahlen von einem gleichförmigen Zufallsbitgenerator
(Algorithmus-Funktionsobjekt)

C-Zufallsbibliothek

Zusätzlich zu den oben beschriebenen Engines und Verteilungen sind auch die Funktionen und Konstanten aus der C-Random-Bibliothek verfügbar, obwohl nicht empfohlen:

Definiert im Header <cstdlib>
generiert eine Pseudo-Zufallszahl
(Funktion)
initialisiert den Pseudo-Zufallszahlengenerator
(Funktion)
maximaler möglicher Wert, generiert durch std::rand
(Makrokonstante)

Beispiel

#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <random>
#include <string>
int main()
{
    // Mit einem echten Zufallswert initialisieren, falls verfügbar
    std::random_device r;
    // Einen zufälligen Mittelwert zwischen 1 und 6 wählen
    std::default_random_engine e1(r());
    std::uniform_int_distribution<int> uniform_dist(1, 6);
    int mean = uniform_dist(e1);
    std::cout << "Zufällig gewählter Mittelwert: " << mean << '\n';
    // Eine Normalverteilung um diesen Mittelwert generieren
    std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937 e2(seed2);
    std::normal_distribution<> normal_dist(mean, 2);
    std::map<int, int> hist;
    for (int n = 0; n != 10000; ++n)
        ++hist[std::round(normal_dist(e2))];
    std::cout << "Normalverteilung um " << mean << ":\n"
              << std::fixed << std::setprecision(1);
    for (auto [x, y] : hist)
        std::cout << std::setw(2) << x << ' ' << std::string(y / 200, '*') << '\n';
}

Mögliche Ausgabe:

Zufällig gewählter Mittelwert: 4
Normalverteilung um 4:
-4
-3
-2
-1
 0 *
 1 ***
 2 ******
 3 ********
 4 *********
 5 ********
 6 ******
 7 ***
 8 *
 9
10
11
12

Siehe auch

C-Dokumentation für Pseudozufallszahlengenerierung