Recientemente encontré una nueva forma de generar números aleatorios en C ++ 11, pero no pude digerir los artículos que leí al respecto (qué es ese motor , término matemático como distribución , "donde todos los enteros producidos son igualmente probables ").
Entonces, ¿alguien puede explicarme?
- ¿Qué son?
- que significan
- como generar
- ¿Cómo trabajan?
- etc
Puede llamarlo todo en una pregunta frecuente sobre la generación de números aleatorios.
rand
, debería echar un vistazo rápido a wikipedia para conocer algunos conceptos básicos de estadística y RNG; de lo contrario, será muy difícil explicarle la razón<random>
y el uso de sus diversas piezas.Respuestas:
La pregunta es demasiado amplia para una respuesta completa, pero permítanme elegir un par de puntos interesantes:
Por qué "igualmente probable"
Suponga que tiene un generador de números aleatorios simple que genera los números 0, 1, ..., 10 cada uno con la misma probabilidad (piense en esto como el clásico
rand()
). Ahora quieres un número aleatorio en el rango 0, 1, 2, cada uno con la misma probabilidad. Su reacción instintiva sería tomarrand() % 3
. Pero espere, los restos 0 y 1 ocurren con más frecuencia que el resto 2, ¡así que esto no es correcto!Es por eso que necesitamos distribuciones adecuadas , que toman una fuente de enteros aleatorios uniformes y los convierten en nuestra distribución deseada, como
Uniform[0,2]
en el ejemplo. ¡Es mejor dejar esto en una buena biblioteca!Motores
Así, en el corazón de toda aleatoriedad hay un buen generador de números pseudoaleatorios que genera una secuencia de números que se distribuye uniformemente en un cierto intervalo, y que idealmente tiene un período muy largo. La implementación estándar de
rand()
no suele ser la mejor y, por lo tanto, es bueno tener una opción. Linear-congruential y el tornado de Mersenne son dos buenas opciones (LG también se usa a menudorand()
); de nuevo, es bueno dejar que la biblioteca se encargue de eso.Cómo funciona
Fácil: primero, configure un motor y siembre. La semilla determina completamente la secuencia completa de números "aleatorios", así que a) use uno diferente (por ejemplo, tomado de
/dev/urandom
) cada vez, yb) guarde la semilla si desea recrear una secuencia de elecciones aleatorias.Ahora podemos crear distribuciones:
... ¡Y usa el motor para crear números aleatorios!
Concurrencia
Una razón más importante para preferir
<random>
sobre lo tradicionalrand()
es que ahora es muy claro y obvio cómo hacer que la generación de números aleatorios sea segura para los subprocesos: proporcione a cada subproceso con su propio motor local de subprocesos, sembrado en una semilla local de subprocesos, o sincronice el acceso al objeto motor.Misc
result_type
, que es el tipo integral correcto para usar con la semilla. Creo que tenía una aplicación con errores una vez que me obligó a forzar la semilla parastd::mt19937
queuint32_t
en x64, con el tiempo esto debe ser fijo y se puede decirMyRNG::result_type seed_val
y por lo tanto hacer que el motor muy fácilmente reemplazable.fuente
std::random_device
vale la pena mencionarlo en lugar de/dev/urandom
std::random_device
Puede encontrar un ejemplo de aquí .Un generador de números aleatorios es una ecuación que, dado un número, le dará un número nuevo. Por lo general, proporciona el primer número o se extrae de algo como la hora del sistema.
Cada vez que solicita un nuevo número, utiliza el número anterior para ejecutar la ecuación.
Un generador de números aleatorios no se considera muy bueno si tiende a producir el mismo número con más frecuencia que otros números. es decir, si quisiera un número aleatorio entre uno y 5 y tuviera esta distribución de números:
2 se genera MUCHO más a menudo que cualquier otro número, por lo que es más probable que se produzca que otros números. Si todos los números fueran iguales, tendría un 20% de posibilidades de obtener cada número cada vez. Para decirlo de otra manera, la distribución anterior es muy desigual porque se favorece el 2. Una distribución con todos los del 20% sería uniforme.
Por lo general, si desea un número aleatorio verdadero, extraerá datos de algo como el clima o alguna otra fuente natural en lugar de un generador de números aleatorios.
fuente