C++-Standardbibliothek <random>
In der C++-Standardbibliothek<random>Die Header-Datei bietet eine Reihe von Werkzeugen zum Generieren von Zufallszahlen, die alles von einfachen Gleichverteilungen bis hin zu komplexen diskreten Verteilungen abdecken und eine breite Palette von Optionen für Anwendungen bieten, die Zufallszahlen benötigen. Diese Werkzeuge sind in Bereichen wie Simulation, Spieleentwicklung und kryptografischen Algorithmen sehr nützlich.
<random>Es unterstützt nicht nur die Generierung von Pseudozufallszahlen, sondern auch Seed-Steuerung, verschiedene Wahrscheinlichkeitsverteilungen usw., sodass Entwickler flexibel Sequenzen von Zufallszahlen generieren können, die bestimmte Anforderungen erfüllen.
<random>Die Bibliothek besteht aus den folgenden drei Hauptkomponenten:
- Zufallszahlen-Engine: Der Kern zur Generierung von Pseudozufallszahlen, der verwendet wird, um die Reproduzierbarkeit und Zufälligkeit des Generierungsprozesses zu steuern.
- Zufallszahlen-Verteilung: Steuert den Typ der Wahrscheinlichkeitsverteilung, der die generierten Werte folgen.
- Zufallszahlen-Adapter: ermöglicht die Anpassung des Engine-Verhaltens, wie z. B.
discard_blockund andere Adapter.
In C++ können Zufallszahlengeneratoren (Random Number Generator, RNG) in zwei Hauptkategorien unterteilt werden:
- Pseudozufallszahlengenerator: Sie verwenden deterministische Algorithmen, um scheinbar zufällige Sequenzen zu erzeugen. Diese Sequenzen sind theoretisch vorhersagbar, aber für die meisten Anwendungen im Allgemeinen zufällig genug.
- Echter Zufallszahlengenerator: Sie erzeugen Zufallszahlen basierend auf physikalischen Prozessen (wie thermisches Rauschen, radioaktiver Zerfall usw.), aber die C++-Standardbibliothek stellt solche Generatoren nicht direkt bereit.
Gängige Zufallszahlen-Engines
| Engine | Beschreibung |
|---|---|
std::default_random_engine | Standard-Zufallszahlen-Engine, mit einer Implementierung, die vom jeweiligen Compiler abhängt. |
std::minstd_rand | Lineare Kongruenz-Engine, die eine gleichmäßige Sequenz von Pseudozufallszahlen erzeugt. |
std::mt19937 | Mersenne-Twister-Algorithmus, geeignet für allgemeine Zufallszahlengenerierung. |
std::mt19937_64 | 64-Bit-Mersenne-Twister-Algorithmus. |
std::ranlux24_base | Vereinfachte Subtract-with-Carry-Engine, die für die hochwertige Generierung verwendet wird. |
std::knuth_b | Knuth-Shuffle-Zufallszahlengenerator. |
Gängige Engines wie z. B.std::mt19937Aufgrund seiner schnellen Generierungsgeschwindigkeit und hohen Generierungsqualität ist es eine weithin empfohlene Engine zur Zufallszahlengenerierung. Der Generator kann außerdemseed()Methode zum Festlegen des Seeds, die die Generierung reproduzierbarer Pseudozufallssequenzen erleichtert.
Typen von Zufallszahlenverteilungen
1. Gleichverteilung
| Distribution | Beschreibung |
|---|---|
std::uniform_int_distribution | Erzeugt eine Gleichverteilung über einen Bereich von Ganzzahlen. |
std::uniform_real_distribution | Erzeugt eine Gleichverteilung über einen Bereich von Gleitkommazahlen. |
std::mt19937 gen(seed); std::uniform_int_distribution<int> dist(1, 100); // 生成 1 到 100 间的整数 int random_int = dist(gen);
2. Normalverteilung
| Distribution | Beschreibung |
|---|---|
std::normal_distribution | Standardnormalverteilung, zentralsymmetrisch, wird oft zur Simulation natürlicher Phänomene verwendet. |
std::lognormal_distribution | Log-Normalverteilung. |
std::mt19937 gen(seed); std::normal_distribution<> dist(0, 1); // 平均值为0,标准差为1 double random_normal = dist(gen);
3. Diskrete Verteilung
| Distribution | Beschreibung |
|---|---|
std::discrete_distribution | Erzeugt Zufallszahlen als Ganzzahlen mit einer Menge spezifischer Wahrscheinlichkeiten. |
std::bernoulli_distribution | Bernoulli-Verteilung, die nur erzeugttrueoderfalse。 |
std::binomial_distribution | Binomialverteilung. |
std::mt19937 gen(seed);
std::discrete_distribution<int> dist({40, 10, 50}); // 概率为40%、10%、50%
int random_discrete = dist(gen);
Syntax
Nutzung<random>Die grundlegenden Schritte der Bibliothek sind wie folgt:
- Header-Dateien einbinden
<random>。 - Erstellen Sie ein Zufallszahlengenerator-Objekt.
- Verwenden Sie die Verteilungsklasse, um Zufallszahlen zu erzeugen.
Beispiel
Grundlegende Zufallszahlen erzeugen
Beispiel
#include <random>
int main() {
// Verwenden Sie ein Random-Device, um einen zufälligen Startwert zu erzeugen
std::random_device rd;
// Verwenden Sie den Zufallsstartwert, um den Mersenne-Twister-Zufallszahlengenerator zu initialisieren
std::mt19937 generator(rd());
// Eine Zufallszahl erzeugen
std::cout << "Zufallszahl: " << generator() << std::endl;
return 0;
}
Ausgabeergebnis:
Random number: 3499211612
Hinweis:Jedes Mal, wenn das Programm ausgeführt wird, können die generierten Zufallszahlen unterschiedlich sein.
Verwendung einer Gleichverteilung
Beispiel
#include <random>
int main() {
// Einen Zufallszahlengenerator erstellen
std::mt19937 generator;
// Einen gleichverteilten Zufallszahlengenerator mit einem Bereich von 1 bis 10 erstellen
std::uniform_int_distribution<int> distribution(1, 10);
// 5 Zufallszahlen erzeugen und ausgeben
for (int i = 0; i < 5; ++i) {
std::cout << "Zufallszahl: " << distribution(generator) << std::endl;
}
return 0;
}
Ausgabeergebnis:
Random number: 7 Random number: 10 Random number: 6 Random number: 2 Random number: 4
Jedes Mal, wenn das Programm ausgeführt wird, kann die ausgegebene Zufallszahlenfolge unterschiedlich sein.
Verwendung einer Normalverteilung
Beispiel
#include <random>
#include <iomanip>
int main() {
// Einen Zufallszahlengenerator erstellen
std::mt19937 generator;
// Einen normalverteilten Zufallszahlengenerator mit Mittelwert 0 und Standardabweichung 1 erstellen
std::normal_distribution<double> distribution(0.0, 1.0);
// Ausgabeformat auf zwei Dezimalstellen setzen
std::cout << std::fixed << std::setprecision(2);
// 5 Zufallszahlen erzeugen und ausgeben
for (int i = 0; i < 5; ++i) {
std::cout << "Zufallszahl: " << distribution(generator) << std::endl;
}
return 0;
}
Random number: -0.15 Random number: 0.13 Random number: -1.87 Random number: 0.46 Random number: -0.21
Verwendung der mt19937-Engine zur Generierung von Zufallszahlen mit verschiedenen Verteilungen:
Beispiel
#include <random>
int main() {
// 1. Seed und Zufallszahlen-Engine setzen
std::random_device rd; // Zufallsgerät erzeugt den Seed
std::mt19937 gen(rd()); // Mersenne-Twister-Engine
// 2. Gleichverteilte Ganzzahlen
std::uniform_int_distribution<> dist_int(1, 100);
std::cout << "Gleichverteilte Ganzzahl: " << dist_int(gen) << std::endl;
// 3. Gleichverteilte Gleitkommazahlen
std::uniform_real_distribution<> dist_real(0.0, 1.0);
std::cout << "Gleichverteilt reell: " << dist_real(gen) << std::endl;
// 4. Normalverteilung
std::normal_distribution<> dist_normal(0, 1);
std::cout << "Normal: " << dist_normal(gen) << std::endl;
// 5. Diskrete Verteilung
std::discrete_distribution<> dist_discrete({10, 20, 70});
std::cout << "Diskret: " << dist_discrete(gen) << std::endl;
return 0;
}
Zufallszahlen-Adapter
Zufallszahlen-Adapter ermöglichen die Anpassung des Erzeugungsverhaltens; es gibt zwei Haupttypen von Adaptern:
std::discard_block_engine: Verwirft eine bestimmte Anzahl generierter Werte und behält nur diejenigen in festgelegten Abständen bei, wird verwendet, um die Zufälligkeit zu reduzieren.std::independent_bits_engine: Erzeugt Zufallszahlen mit einer festgelegten Anzahl von Bits, wodurch sich direkt Binärdaten einfach erzeugen lassen.
Beispiel
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::discard_block_engine<std::mt19937, 3, 2> discard_engine(gen);
std::cout << "Discard-Block-Zufallszahl: " << discard_engine() << std::endl;
return 0;
}
Häufige Verwendung
- Verwenden Sie einen Seed, um eine reproduzierbare Zufallsfolge zu erzeugen: Die Angabe desselben Seeds bewirkt, dass jeder Lauf dieselbe Folge erzeugt.
- Zufallszahlen mit unterschiedlichen Verteilungen erzeugen: Wählen Sie eine Verteilungsfunktion, die zum Anwendungsszenario passt, um reale Probleme besser zu simulieren.
- Anpassen der Generatorleistung: Verwenden Sie verschiedene Zufalls-Engines, um Erzeugungsleistung und Genauigkeit auszubalancieren.