c++ - Aumente el generador de números aleatorios
boost random (3)
¿Alguien tiene un generador de números aleatorios de refuerzo favorito y puede explicar un poco sobre cómo implementarlo en el código. Estoy tratando de hacer funcionar al misterioso tornado y me preguntaba si alguien tenía preferencia por uno de los otros.
Encontré este link que ofrece una buena descripción de las propiedades de diferentes generadores de números aleatorios. He copiado la tabla del enlace de arriba para mayor comodidad:
+-----------------------+-------------------+-----------------------------+------------------------+ | generator | length of cycle | approx. memory requirements | approx. relative speed | +-----------------------+-------------------+-----------------------------+------------------------+ | minstd_rand | 2^31-2 | sizeof(int32_t) | 40 | | rand48 | 2^48-1 | sizeof(uint64_t) | 80 | | lrand48 (C library) | 2^48-1 | - | 20 | | ecuyer1988 | approx. 2^61 | 2*sizeof(int32_t) | 20 | | kreutzer1986 | ? | 1368*sizeof(uint32_t) | 60 | | hellekalek1995 | 2^31-1 | sizeof(int32_t) | 3 | | mt11213b | 2^11213-1 | 352*sizeof(uint32_t) | 100 | | mt19937 | 2^19937-1 | 625*sizeof(uint32_t) | 100 | | lagged_fibonacci607 | approx. 2^32000 | 607*sizeof(double) | 150 | | lagged_fibonacci1279 | approx. 2^67000 | 1279*sizeof(double) | 150 | | lagged_fibonacci2281 | approx. 2^120000 | 2281*sizeof(double) | 150 | | lagged_fibonacci3217 | approx. 2^170000 | 3217*sizeof(double) | 150 | | lagged_fibonacci4423 | approx. 2^230000 | 4423*sizeof(double) | 150 | | lagged_fibonacci9689 | approx. 2^510000 | 9689*sizeof(double) | 150 | | lagged_fibonacci19937 | approx. 2^1050000 | 19937*sizeof(double) | 150 | | lagged_fibonacci23209 | approx. 2^1200000 | 23209*sizeof(double) | 140 | | lagged_fibonacci44497 | approx. 2^2300000 | 44497*sizeof(double) | 60 | +-----------------------+-------------------+-----------------------------+------------------------+
duración del ciclo : duración de la secuencia de números aleatorios antes de que comience a repetirse
Este código está adaptado del manual de impulso en http://www.boost.org/doc/libs/1_42_0/libs/random/index.html :
#include <iostream>
#include "boost/random.hpp"
#include "boost/generator_iterator.hpp"
using namespace std;
int main() {
typedef boost::mt19937 RNGType;
RNGType rng;
boost::uniform_int<> one_to_six( 1, 6 );
boost::variate_generator< RNGType, boost::uniform_int<> >
dice(rng, one_to_six);
for ( int i = 0; i < 6; i++ ) {
int n = dice();
cout << n << endl;
}
}
Para explicar los bits:
mt19937
es el generador twister demt19937
, que genera los números aleatorios crudos. Un typedef se usa aquí para que pueda cambiar fácilmente el tipo de generador de números aleatorios.rng
es una instancia del generador de twister.one_to_six
es una instancia de una distribución . Esto especifica los números que queremos generar y la distribución que siguen. Aquí queremos 1 a 6, distribuidos uniformemente.dice
son lo que toma los números brutos y la distribución, y crea para nosotros los números que realmente queremos.dice()
es una llamada aloperator()
para el objeto dedice
, que obtiene el siguiente número aleatorio después de la distribución, simulando un lanzamiento de dados de seis caras al azar.
Tal como está, este código produce la misma secuencia de lanzamientos de dados cada vez. Puedes aleatorizar el generador en su constructor:
RNGType rng( time(0) );
o usando su miembro seed ().
No hay un RNG único para todos. A veces, las propiedades estadísticas son importantes, a veces la criptología, a veces la velocidad bruta.