Namespaces
Variants

Pseudo-random number generation

From cppreference.net

La bibliothèque de nombres aléatoires fournit des classes qui génèrent des nombres aléatoires et pseudo-aléatoires. Ces classes incluent :

  • Générateurs de bits aléatoires uniformes (URBG), qui incluent à la fois les moteurs de nombres aléatoires, qui sont des générateurs de nombres pseudo-aléatoires produisant des séquences d'entiers avec une distribution uniforme, et les générateurs de nombres véritablement aléatoires (si disponibles).
  • Distributions de nombres aléatoires (par ex. uniform , normal , ou poisson distributions ) qui convertissent la sortie des URBG en diverses distributions statistiques.

Les générateurs de nombres aléatoires (URBG) et les distributions sont conçus pour être utilisés ensemble afin de produire des valeurs aléatoires. Tous les moteurs de génération de nombres aléatoires peuvent être spécifiquement initialisés, sérialisés et désérialisés pour une utilisation avec des simulateurs reproductibles.

Table des matières

Générateurs de bits aléatoires uniformes

Un générateur de bits aléatoire uniforme est un objet fonction retournant des valeurs entières non signées telles que chaque valeur dans la plage des résultats possibles a (idéalement) une probabilité égale d'être retournée.

Tous les générateurs de bits aléatoires uniformes satisfont aux UniformRandomBitGenerator exigences. C++20 définit également un uniform_random_bit_generator concept.

Défini dans l'en-tête <random>
spécifie qu'un type est qualifié comme générateur uniforme de bits aléatoires
(concept)

Moteurs de génération de nombres aléatoires

Un moteur de génération de nombres aléatoires (communément appelé moteur ) est un générateur uniforme de bits aléatoires qui produit des nombres pseudo-aléatoires en utilisant des données d'amorçage comme source d'entropie.

À tout moment, un moteur e de type E possède un état e i pour un entier non négatif i . Lors de sa construction, e a un état initial e 0 , qui est déterminé par les paramètres du moteur et une graine initiale (ou séquence de graines).

Les propriétés suivantes sont toujours définies pour tout type de moteur E :

  • La taille de l'état de E en multiples de la taille de E::result_type (c'est-à-dire ( sizeof e i ) / sizeof ( E :: result_type ) ).
  • L' algorithme de transition TA par lequel l'état e e i est avancé vers son état successeur e i+1 (c'est-à-dire TA ( e i ) == e i+1 ).
  • L' algorithme de génération GA par lequel l'état de e est mappé à une valeur de type E::result_type , le résultat est un nombre pseudo-aléatoire.

Une séquence de nombres pseudo-aléatoires peut être générée en appelant alternativement TA et GA .

La bibliothèque standard fournit les implémentations de trois classes différentes d'algorithmes de génération de nombres pseudo-aléatoires sous forme de modèles de classe, permettant ainsi la personnalisation des algorithmes. Le choix du moteur à utiliser implique plusieurs compromis :

  • Le générateur congruentiel linéaire est modérément rapide et nécessite un très faible stockage pour l'état.
  • Le générateur de Mersenne Twister est plus lent et nécessite un stockage d'état plus important, mais avec les bons paramètres, il possède la séquence non répétitive la plus longue avec les caractéristiques spectrales les plus souhaitables (pour une définition donnée de souhaitable).
  • Le générateur à soustraction avec retenue est très rapide même sur les processeurs sans jeux d'instructions arithmétiques avancés, au détriment d'un stockage d'état plus important et parfois de caractéristiques spectrales moins souhaitables.
  • Le moteur Philox est un générateur de nombres aléatoires basé sur un compteur . Il possède un état réduit et une longue période (pas moins de 2^130) et est destiné aux simulations de Monte-Carlo nécessitant une génération massivement parallèle de nombres aléatoires. Il est facilement vectorisable et parallélisable et est implémenté dans des bibliothèques optimisées pour GPU.
(depuis C++26)

Aucun de ces générateurs de nombres aléatoires n'est cryptographiquement sécurisé . Comme pour toute opération sécurisée, une bibliothèque cryptographique doit être utilisée à cet effet (par exemple OpenSSL RAND_bytes ).

Tous les types instanciés à partir de ces modèles satisfont aux RandomNumberEngine exigences.

Défini dans l'en-tête <random>
implémente l'algorithme congruentiel linéaire
(modèle de classe)
implémente l'algorithme Mersenne twister
(modèle de classe)
implémente l'algorithme de soustraction avec retenue ( Fibonacci retardé )
(modèle de classe)
un générateur parallélisable basé sur un compteur
(modèle de classe)

Adaptateurs de moteurs de génération de nombres aléatoires

Les adaptateurs de moteur de nombres aléatoires génèrent des nombres pseudo-aléatoires en utilisant un autre moteur de nombres aléatoires comme source d'entropie. Ils sont généralement utilisés pour modifier les caractéristiques spectrales du moteur sous-jacent.

Défini dans l'en-tête <random>
ignore certaines sorties d'un moteur de nombres aléatoires
(modèle de classe)
regroupe la sortie d'un moteur de nombres aléatoires en blocs d'un nombre spécifié de bits
(modèle de classe)
délivre la sortie d'un moteur de nombres aléatoires dans un ordre différent
(modèle de classe)

Générateurs de nombres aléatoires prédéfinis

Plusieurs algorithmes populaires spécifiques sont prédéfinis.

Défini dans l'en-tête <random>
Type Définition
minstd_rand0 (C++11) std:: linear_congruential_engine < std:: uint_fast32_t ,
16807 , 0 , 2147483647 >

Découvert en 1969 par Lewis, Goodman et Miller, adopté comme "Standard minimal" en 1988 par Park et Miller

minstd_rand (C++11)

std:: linear_congruential_engine < std:: uint_fast32_t ,
48271 , 0 , 2147483647 >
Nouveau "standard minimum", recommandé par Park, Miller et Stockmeyer en 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 >
Mersenne Twister 32 bits de Matsumoto et 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 >
Mersenne Twister 64 bits par Matsumoto et 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 >

Générateur RANLUX 24 bits par Martin Lüscher et Fred James, 1994

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

Générateur RANLUX 48 bits par Martin Lüscher et 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) un type RandomNumberEngine défini par l'implémentation

Nombres aléatoires non déterministes

std::random_device est un générateur de bits aléatoires uniforme non déterministe, bien que les implémentations soient autorisées à implémenter std::random_device en utilisant un moteur de nombres pseudo-aléatoires s'il n'y a pas de support pour la génération de nombres aléatoires non déterministes.

générateur de nombres aléatoires non déterministe utilisant une source d'entropie matérielle
(classe)

Distributions de nombres aléatoires

Une distribution de nombres aléatoires post-traite la sortie d'un URBG de telle manière que la sortie résultante soit distribuée selon une fonction de densité de probabilité statistique définie.

Les distributions de nombres aléatoires satisfont RandomNumberDistribution .

Défini dans l'en-tête <random>
Distributions uniformes
produit des valeurs entières uniformément réparties sur une plage
(modèle de classe)
produit des valeurs réelles uniformément réparties sur un intervalle
(modèle de classe)
Distributions de Bernoulli
produit des valeurs bool selon une distribution de Bernoulli
(classe)
produit des valeurs entières selon une distribution binomiale
(modèle de classe)
produit des valeurs entières selon une distribution binomiale négative
(modèle de classe)
produit des valeurs entières selon une distribution géométrique
(modèle de classe)
Distributions de Poisson
produit des valeurs entières selon une distribution de Poisson
(modèle de classe)
produit des valeurs réelles selon une distribution exponentielle
(modèle de classe)
produit des valeurs réelles selon une distribution gamma
(modèle de classe)
produit des valeurs réelles selon une distribution de Weibull
(modèle de classe)
produit des valeurs réelles selon une distribution des valeurs extrêmes
(modèle de classe)
Distributions normales
produit des valeurs réelles selon une distribution normale standard (gaussienne)
(modèle de classe)
produit des valeurs réelles selon une distribution log-normale
(modèle de classe)
produit des valeurs réelles selon une distribution du chi carré
(modèle de classe)
produit des valeurs réelles selon une distribution de Cauchy
(modèle de classe)
produit des valeurs réelles selon une distribution F de Fisher
(modèle de classe)
produit des valeurs réelles selon une distribution de Student
(modèle de classe)
Distributions d'échantillonnage
produit des valeurs entières selon une distribution discrète
(modèle de classe)
produit des valeurs réelles distribuées sur des sous-intervalles constants
(modèle de classe)
produit des valeurs réelles distribuées sur des sous-intervalles définis
(modèle de classe)

Utilitaires

Défini dans l'en-tête <random>
répartit uniformément les valeurs réelles de précision donnée sur [ 0 , 1 )
(modèle de fonction)
(C++11)
générateur de séquence d'amorçage brouillée à élimination de biais à usage général
(classe)

Algorithmes de génération de nombres aléatoires

Défini dans l'en-tête <random>
remplit une plage avec des nombres aléatoires provenant d'un générateur de bits aléatoire uniforme
(objet fonction algorithme)

Bibliothèque d'aléatoire C

En plus des moteurs et distributions décrits ci-dessus, les fonctions et constantes de la bibliothèque aléatoire C sont également disponibles bien que non recommandées :

Défini dans l'en-tête <cstdlib>
génère un nombre pseudo-aléatoire
(fonction)
initialise le générateur de nombres pseudo-aléatoires
(fonction)
valeur maximale possible générée par std::rand
(constante macro)

Exemple

#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <random>
#include <string>
int main()
{
    // Initialiser avec une valeur aléatoire réelle, si disponible
    std::random_device r;
    // Choisir une moyenne aléatoire entre 1 et 6
    std::default_random_engine e1(r());
    std::uniform_int_distribution<int> uniform_dist(1, 6);
    int mean = uniform_dist(e1);
    std::cout << "Moyenne choisie aléatoirement : " << mean << '\n';
    // Générer une distribution normale autour de cette moyenne
    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 << "Distribution normale autour de " << mean << ":\n"
              << std::fixed << std::setprecision(1);
    for (auto [x, y] : hist)
        std::cout << std::setw(2) << x << ' ' << std::string(y / 200, '*') << '\n';
}

Sortie possible :

Moyenne choisie aléatoirement : 4
Distribution normale autour de 4 :
-4
-3
-2
-1
 0 *
 1 ***
 2 ******
 3 ********
 4 *********
 5 ********
 6 ******
 7 ***
 8 *
 9
10
11
12

Voir aussi

Documentation C pour Génération de nombres pseudo-aléatoires