2011-01-24 7 views
8

Me gustaría restablecer secuencias aleatorias mediante el uso de diferentes números de inicialización. Cuando se ejecuta este código de prueba:Configuración del aumento de semilla :: aleatorio

boost::mt19937 gener(1); 
boost::normal_distribution<> normal(0,1); 
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal); 
cout << rng() << endl; 
cout << rng() << endl; 
cout << rng() << endl; 
gener.seed(2); 
cout << rng() << endl; 
cout << rng() << endl; 
gener.seed(1); 
cout << rng() << endl; 
gener.seed(2); 
cout << rng() << endl; 
gener.seed(3); 
cout << rng() << endl; 

me sale el siguiente resultado:

# seed(1) via constructor 
-2.971829031 
1.706951063 
-0.430498971 
# seed(2) 
-2.282022417 
-0.5887503675 
# seed(1) 
0.2504171986 
# seed(2) 
-0.5887503675 
# seed(3) 
0.2504171986 

Obviamente estoy haciendo algo muy mal. ¿Cómo puedo superar este problema?

Respuesta

14

Siguiendo Jim, Alan y Igor sugerencias hecho algunos cambios en el código: rng.engine().seed() en lugar de gener.seed(), y llamó rng.distribution().reset() después de la llamada a rng.engine().seed() y funcionó a las mil maravillas.

¡Muchas gracias!

+3

¡Me alegro de que funcionó! Por cierto, se te permite (y se te alienta) aceptar tu propia respuesta, especialmente si se necesita una combinación de ideas de varias personas para resolver tu problema. –

1

Creo que boost::variate_generator<> hace una copia de su objeto boost::mt19937 gener. Así que cuando resembró su copia de gener, no tiene ningún efecto en el objeto rng que ya se ha construido . Construir un nuevo objeto rng cada vez que replantee debería darle el comportamiento que desea (exención de responsabilidad: ¡no probado!)

+0

Creo que la resiembra está teniendo algún efecto sobre RNG, porque estoy consiguiendo valores repetidos -0.5887503675 y 0,2504171986. Pero desafortunadamente no es para nada lo que esperaría. –

+0

Excelente para ver el problema resuelto, pero ¿puedo preguntar por qué 'boost :: variate_generator <>' hace una copia de 'gener' en este caso? Creo que OP pasó la referencia al escribir 'boost :: variate_generator >', ¿me falta algo? ... – Vokram

5

Debe llamar a normal.reset() después de la llamada a gener.seed(). Esto se especifica para garantizar que la salida de normal no dependa de ninguna salida anterior de gener.

(la distribución es, probablemente, el almacenamiento en caché un estado que necesita para limpiar.)

+0

Sí, parece un problema de almacenamiento en caché. Hice lo que me sugirió, pero sigo obteniendo los mismos resultados ... –

+2

Los RNG distribuidos normalmente usan la [Transformada de Box-Muller] (http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform) que genera números aleatorios por parejas (ver: [Ejemplos de Recetas Numéricas] (http://dimacs.rutgers.edu/~graham/code.html)) – Mike

1

Excelente para ver el problema resuelto! Pero supongo que acabo de descubrir qué método de Alan no funcionaría ...

Al escribir boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal), no creó otra copia de gener porque es una llamada por referencia, pero se hizo crear otra copia de normal con el variate_generate.

Por lo tanto, en lugar de normal.reset, que solo restablece el original normal, debe usar rng.distribution().reset(). Pero puede mantener gener.seed(), que sospecho tendrá el mismo efecto que rng.engine().seed().

Lo probé en mi código, y funcionó como se esperaba.

Bueno, por si acaso a alguien le importaría :)

Cuestiones relacionadas