Namespaces
Variants

Pseudo-random number generation

From cppreference.net

La biblioteca de números aleatorios proporciona clases que generan números aleatorios y pseudoaleatorios. Estas clases incluyen:

  • Generadores de bits aleatorios uniformes (URBGs), que incluyen tanto motores de números aleatorios, que son generadores pseudoaleatorios que producen secuencias de enteros con distribución uniforme, como generadores verdaderos de números aleatorios (si están disponibles).
  • Distribuciones de números aleatorios (p. ej. uniform , normal , o poisson distributions ) que convierten la salida de los URBGs en varias distribuciones estadísticas.

Los URBG y las distribuciones están diseñados para ser utilizados conjuntamente para producir valores aleatorios. Todos los motores de números aleatorios pueden ser específicamente sembrados, serializados y deserializados para su uso con simuladores repetibles.

Contenidos

Generadores uniformes de bits aleatorios

Un generador uniforme de bits aleatorios es un objeto función que devuelve valores enteros sin signo de modo que cada valor en el rango de resultados posibles tiene (idealmente) igual probabilidad de ser devuelto.

Todos los generadores uniformes de bits aleatorios cumplen con los UniformRandomBitGenerator requisitos. C++20 también define un uniform_random_bit_generator concepto.

Definido en el encabezado <random>
especifica que un tipo califica como generador uniforme de bits aleatorios
(concepto)

Motores de números aleatorios

Un motor de números aleatorios (comúnmente abreviado como motor ) es un generador uniforme de bits aleatorios que genera números pseudoaleatorios utilizando datos de semilla como fuente de entropía.

En cualquier momento dado, un motor e de tipo E tiene un estado e i para algún entero no negativo i . Al construirse, e tiene un estado inicial e 0 , que está determinado por los parámetros del motor y una semilla inicial (o secuencia de semillas).

Las siguientes propiedades están siempre definidas para cualquier tipo de motor E :

  • El tamaño del estado de E en múltiplos del tamaño de E::result_type (es decir, ( sizeof e i ) / sizeof ( E :: result_type ) ).
  • El algoritmo de transición TA mediante el cual e avanza su estado e i a su estado sucesor e i+1 (es decir, TA ( e i ) == e i+1 ).
  • El algoritmo de generación GA mediante el cual e mapea su estado a un valor de tipo E::result_type , el resultado es un número pseudoaleatorio.

Una secuencia de números pseudoaleatorios puede generarse llamando alternativamente a TA y GA .

La biblioteca estándar proporciona las implementaciones de tres clases diferentes de algoritmos de generación de números pseudoaleatorios como plantillas de clase, de modo que los algoritmos pueden personalizarse. La elección de qué motor usar implica una serie de compensaciones:

  • El linear congruential engine es moderadamente rápido y tiene un requisito de almacenamiento de estado muy pequeño.
  • El Mersenne twister engine es más lento y tiene mayores requisitos de almacenamiento de estado, pero con los parámetros correctos tiene la secuencia no repetitiva más larga con las características espectrales más deseables (para una definición dada de deseable).
  • El subtract with carry engine es muy rápido incluso en procesadores sin conjuntos de instrucciones aritméticas avanzadas, a costa de un mayor almacenamiento de estado y a veces características espectrales menos deseables.
  • El motor Philox es un generador de números aleatorios basado en contador . Tiene un estado pequeño y un período largo (no menor que 2^130) y está destinado para su uso en simulaciones de Monte Carlo que requieren generación masivamente paralela de números aleatorios. Se vectoriza y paraleliza fácilmente y está implementado en bibliotecas optimizadas para GPU.
(desde C++26)

Ninguno de estos motores de números aleatorios es criptográficamente seguro . Como con cualquier operación segura, debería utilizarse una biblioteca criptográfica para este propósito (por ejemplo OpenSSL RAND_bytes ).

Todos los tipos instanciados a partir de estas plantillas cumplen con los RandomNumberEngine requisitos.

Definido en el encabezado <random>
implementa el algoritmo congruencial lineal
(plantilla de clase)
implementa el algoritmo Mersenne twister
(plantilla de clase)
implementa un algoritmo de resta con acarreo ( Fibonacci retardado )
(plantilla de clase)
un generador paralelizable basado en contador
(plantilla de clase)

Adaptadores de motores de números aleatorios

Los adaptadores de motor de números aleatorios generan números pseudoaleatorios utilizando otro motor de números aleatorios como fuente de entropía. Generalmente se utilizan para alterar las características espectrales del motor subyacente.

Definido en el encabezado <random>
descarta parte de la salida de un motor de números aleatorios
(plantilla de clase)
empaqueta la salida de un motor de números aleatorios en bloques de un número específico de bits
(plantilla de clase)
entrega la salida de un motor de números aleatorios en un orden diferente
(plantilla de clase)

Generadores de números aleatorios predefinidos

Se predefinen varios algoritmos populares específicos.

Definido en el encabezado <random>
Tipo Definición
minstd_rand0 (C++11) std:: linear_congruential_engine < std:: uint_fast32_t ,
16807 , 0 , 2147483647 >

Descubierto en 1969 por Lewis, Goodman y Miller, adoptado como "Estándar mínimo" en 1988 por Park y Miller

minstd_rand (C++11)

std:: linear_congruential_engine < std:: uint_fast32_t ,
48271 , 0 , 2147483647 >
Nuevo "estándar mínimo", recomendado por Park, Miller y 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 de 32 bits por Matsumoto y 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 de 64 bits por Matsumoto y 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 >

Generador RANLUX de 24 bits por Martin Lüscher y Fred James, 1994

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

Generador RANLUX de 48 bits por Martin Lüscher y 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 tipo RandomNumberEngine definido por la implementación

Números aleatorios no deterministas

std::random_device es un generador no determinista de bits aleatorios uniformes, aunque se permite que las implementaciones utilicen std::random_device mediante un motor de números pseudoaleatorios si no hay soporte para la generación no determinista de números aleatorios.

generador de números aleatorios no determinista que utiliza una fuente de entropía de hardware
(clase)

Distribuciones de números aleatorios

Una distribución de números aleatorios postprocesa la salida de un URBG de tal manera que la salida resultante se distribuye de acuerdo con una función de densidad de probabilidad estadística definida.

Las distribuciones de números aleatorios satisfacen RandomNumberDistribution .

Definido en el encabezado <random>
Distribuciones uniformes
produce valores enteros distribuidos uniformemente en un rango
(plantilla de clase)
produce valores reales distribuidos uniformemente a lo largo de un rango
(plantilla de clase)
Distribuciones de Bernoulli
produce bool valores según una distribución de Bernoulli
(clase)
produce valores enteros en una distribución binomial
(plantilla de clase)
produce valores enteros según una distribución binomial negativa
(plantilla de clase)
produce valores enteros en una distribución geométrica
(plantilla de clase)
Distribuciones de Poisson
produce valores enteros según una distribución de Poisson
(plantilla de clase)
produce valores reales en una distribución exponencial
(plantilla de clase)
produce valores reales según una distribución gamma
(plantilla de clase)
produce valores reales según una distribución Weibull
(plantilla de clase)
produce valores reales en una distribución de valor extremo
(plantilla de clase)
Distribuciones normales
produce valores reales en una distribución normal estándar (Gaussiana)
(plantilla de clase)
produce valores reales en una distribución logarítmica normal
(plantilla de clase)
produce valores reales en una distribución chi-cuadrado
(plantilla de clase)
produce valores reales en una distribución de Cauchy
(plantilla de clase)
produce valores reales en una distribución F de Fisher
(plantilla de clase)
produce valores reales en una distribución t de Student
(plantilla de clase)
Distribuciones de muestreo
produce valores enteros en una distribución discreta
(plantilla de clase)
produce valores reales distribuidos en subintervalos constantes
(plantilla de clase)
produce valores reales distribuidos en subintervalos definidos
(plantilla de clase)

Utilidades

Definido en el encabezado <random>
distribuye uniformemente valores reales de precisión dada a través de [ 0 , 1 )
(plantilla de función)
(C++11)
generador de secuencia de semillas general con eliminación de sesgos y mezcla
(clase)

Algoritmos de números aleatorios

Definido en el encabezado <random>
llena un rango con números aleatorios de un generador uniforme de bits aleatorios
(objeto función de algoritmo)

Biblioteca aleatoria de C

Además de los motores y distribuciones descritos anteriormente, las funciones y constantes de la biblioteca aleatoria de C también están disponibles aunque no se recomiendan:

Definido en el encabezado <cstdlib>
genera un número pseudoaleatorio
(función)
inicializa el generador de números pseudoaleatorios
(función)
valor máximo posible generado por std::rand
(constante macro)

Ejemplo

#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <random>
#include <string>
int main()
{
    // Semilla con un valor aleatorio real, si está disponible
    std::random_device r;
    // Elegir una media aleatoria entre 1 y 6
    std::default_random_engine e1(r());
    std::uniform_int_distribution<int> uniform_dist(1, 6);
    int mean = uniform_dist(e1);
    std::cout << "Media elegida aleatoriamente: " << mean << '\n';
    // Generar una distribución normal alrededor de esa media
    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 << "Distribución normal alrededor de " << mean << ":\n"
              << std::fixed << std::setprecision(1);
    for (auto [x, y] : hist)
        std::cout << std::setw(2) << x << ' ' << std::string(y / 200, '*') << '\n';
}

Salida posible:

Media elegida aleatoriamente: 4
Distribución normal alrededor de 4:
-4
-3
-2
-1
 0 *
 1 ***
 2 ******
 3 ********
 4 *********
 5 ********
 6 ******
 7 ***
 8 *
 9
10
11
12

Véase también

Documentación de C para Generación de números pseudoaleatorios