Bibliothèque standard C++ <random>
Dans la bibliothèque standard C++<random>Le fichier d'en-tête fournit un ensemble d'outils pour générer des nombres aléatoires, couvrant tout, des simples distributions uniformes aux distributions discrètes complexes, offrant un large éventail d'options pour les applications qui nécessitent des nombres aléatoires. Ces outils sont très utiles dans des domaines tels que la simulation, le développement de jeux et les algorithmes cryptographiques.
<random>Il prend non seulement en charge la génération de nombres pseudo-aléatoires, mais aussi le contrôle de graine, diverses distributions de probabilité, etc., permettant aux développeurs de générer de manière flexible des séquences de nombres aléatoires répondant à des exigences spécifiques.
<random>La bibliothèque se compose des trois principaux composants suivants :
- Moteur de nombres aléatoires: Le cœur de la génération de nombres pseudo-aléatoires, utilisé pour contrôler la reproductibilité et le caractère aléatoire du processus de génération.
- Distribution de nombres aléatoires: Contrôle le type de distribution de probabilité que suivent les valeurs générées.
- Adaptateur de nombres aléatoires: permet d'ajuster le comportement du moteur, tel que
discard_blocket d'autres adaptateurs.
En C++, les générateurs de nombres aléatoires (Random Number Generator, RNG) peuvent être divisés en deux catégories principales :
- Générateur de nombres pseudo-aléatoires: ils utilisent des algorithmes déterministes pour générer des séquences apparemment aléatoires. Ces séquences sont théoriquement prévisibles, mais sont généralement suffisamment aléatoires pour la plupart des applications.
- Générateur de nombres véritablement aléatoires: ils génèrent des nombres aléatoires à partir de processus physiques (tels que le bruit thermique, la désintégration radioactive, etc.), mais la bibliothèque standard C++ ne fournit pas directement de tels générateurs.
Moteurs de génération de nombres aléatoires courants
| Moteur | Description |
|---|---|
std::default_random_engine | Moteur de nombres aléatoires par défaut, avec une implémentation qui dépend du compilateur spécifique. |
std::minstd_rand | Moteur congruentiel linéaire, produisant une séquence uniforme de nombres pseudo-aléatoires. |
std::mt19937 | Algorithme Mersenne Twister, adapté à la génération de nombres aléatoires à usage général. |
std::mt19937_64 | Algorithme Mersenne Twister 64 bits. |
std::ranlux24_base | Moteur simplifié « subtract-with-carry », utilisé pour une génération de haute qualité. |
std::knuth_b | Générateur de nombres aléatoires par mélange de Knuth. |
Moteurs courants tels questd::mt19937En raison de sa vitesse de génération rapide et de sa qualité de génération élevée, c'est un moteur de génération de nombres aléatoires largement recommandé. Le générateur peut également utiliserseed()Méthode pour spécifier la graine, facilitant la génération de séquences pseudo-aléatoires reproductibles.
Types de distribution de nombres aléatoires
1. Distribution uniforme
| Distribution | Description |
|---|---|
std::uniform_int_distribution | Génère une distribution uniforme sur un intervalle d'entiers. |
std::uniform_real_distribution | Génère une distribution uniforme sur un intervalle de nombres à virgule flottante. |
std::mt19937 gen(seed); std::uniform_int_distribution<int> dist(1, 100); // 生成 1 到 100 间的整数 int random_int = dist(gen);
2. Distribution normale
| Distribution | Description |
|---|---|
std::normal_distribution | Distribution normale standard, à symétrie centrale, souvent utilisée pour simuler des phénomènes naturels. |
std::lognormal_distribution | Distribution log-normale. |
std::mt19937 gen(seed); std::normal_distribution<> dist(0, 1); // 平均值为0,标准差为1 double random_normal = dist(gen);
3. Distribution discrète
| Distribution | Description |
|---|---|
std::discrete_distribution | Génère des nombres aléatoires sous forme d'entiers avec un ensemble de probabilités spécifiques. |
std::bernoulli_distribution | Distribution de Bernoulli, qui ne génère quetrueoufalse。 |
std::binomial_distribution | Loi binomiale. |
std::mt19937 gen(seed);
std::discrete_distribution<int> dist({40, 10, 50}); // 概率为40%、10%、50%
int random_discrete = dist(gen);
Syntaxe
Utilisation<random>Les étapes de base de la bibliothèque sont les suivantes :
- Inclure les fichiers d'en-tête
<random>。 - Créez un objet générateur de nombres aléatoires.
- Utilisez la classe de distribution pour générer des nombres aléatoires.
Exemple
Générer des nombres aléatoires de base
Exemple
#include <random>
int main() {
// Utiliser un dispositif aléatoire pour créer une graine aléatoire
std::random_device rd;
// Utiliser la graine aléatoire pour initialiser le générateur de nombres aléatoires Mersenne Twister
std::mt19937 generator(rd());
// Générer un nombre aléatoire
std::cout << "Nombre aléatoire : " << generator() << std::endl;
return 0;
}
Résultat de sortie :
Random number: 3499211612
Remarque :Chaque fois que le programme s'exécute, les nombres aléatoires générés peuvent être différents.
Utilisation d'une distribution uniforme
Exemple
#include <random>
int main() {
// Créer un générateur de nombres aléatoires
std::mt19937 generator;
// Créer un générateur de nombres aléatoires suivant une distribution uniforme avec une plage de 1 à 10
std::uniform_int_distribution<int> distribution(1, 10);
// Générer et afficher 5 nombres aléatoires
for (int i = 0; i < 5; ++i) {
std::cout << "Nombre aléatoire : " << distribution(generator) << std::endl;
}
return 0;
}
Résultat de sortie :
Random number: 7 Random number: 10 Random number: 6 Random number: 2 Random number: 4
Chaque fois que le programme s'exécute, la séquence de nombres aléatoires produite peut être différente.
Utilisation d'une distribution normale
Exemple
#include <random>
#include <iomanip>
int main() {
// Créer un générateur de nombres aléatoires
std::mt19937 generator;
// Créer un générateur de nombres aléatoires suivant une distribution normale avec une moyenne de 0 et un écart-type de 1
std::normal_distribution<double> distribution(0.0, 1.0);
// Définir le format de sortie à deux décimales
std::cout << std::fixed << std::setprecision(2);
// Générer et afficher 5 nombres aléatoires
for (int i = 0; i < 5; ++i) {
std::cout << "Nombre aléatoire : " << 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
Utilisation du moteur mt19937 pour générer des nombres aléatoires avec différentes distributions :
Exemple
#include <random>
int main() {
// 1. Définir la graine et le moteur de nombres aléatoires
std::random_device rd; // Le dispositif aléatoire génère la graine
std::mt19937 gen(rd()); // Moteur Mersenne Twister
// 2. Entiers uniformément distribués
std::uniform_int_distribution<> dist_int(1, 100);
std::cout << "Entier uniforme : " << dist_int(gen) << std::endl;
// 3. Nombres à virgule flottante uniformément distribués
std::uniform_real_distribution<> dist_real(0.0, 1.0);
std::cout << "Réel uniforme : " << dist_real(gen) << std::endl;
// 4. Loi normale
std::normal_distribution<> dist_normal(0, 1);
std::cout << "Normale : " << dist_normal(gen) << std::endl;
// 5. Loi discrète
std::discrete_distribution<> dist_discrete({10, 20, 70});
std::cout << "Discrète : " << dist_discrete(gen) << std::endl;
return 0;
}
Adaptateur de nombres aléatoires
Les adaptateurs de nombres aléatoires permettent d'ajuster le comportement de génération ; il existe deux principaux types d'adaptateurs :
std::discard_block_engine: Rejette un certain nombre de valeurs générées et ne conserve que celles qui se trouvent à des intervalles spécifiés, utilisé pour réduire le caractère aléatoire.std::independent_bits_engine: Génère des nombres aléatoires avec un nombre de bits spécifié, ce qui facilite la génération directe de données binaires.
Exemple
#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 << "Nombre aléatoire du bloc discard : " << discard_engine() << std::endl;
return 0;
}
Utilisation courante
- Utiliser une graine pour générer une séquence aléatoire reproductible: spécifier la même graine fait que chaque exécution génère la même séquence.
- Générer des nombres aléatoires avec différentes distributions: Choisissez une fonction de distribution adaptée au scénario d'application pour mieux simuler des problèmes du monde réel.
- Ajustement des performances du générateur: Utilisez différents moteurs aléatoires pour équilibrer les performances de génération et la précision.