2009-12-04 6 views
10

.cpp principalimpulso :: aleatoria generar la misma cantidad cada vez

#include  "stdafx.h" 
#include  "random_generator.h" 


     int 
main (int argc, char *argv[]) 
{ 
     cout.setf(ios::fixed); 
     base_generator_type base_generator; 
     int max = pow(10, 2); 
     distribution_type dist(1, max); 

     boost::variate_generator<base_generator_type&, 
distribution_type > uni(base_generator, dist); 
     for (int i=0; i<10; i++) { 
       //cout << random_number(2) << endl; 
       cout << uni() << endl; 
     } 

     return EXIT_SUCCESS; 

}        /* ---------- end of function main ---------- */ 

random_gemerator.h

#include  "stdafx.h" 

#include  <boost/random.hpp> 
#include  <boost/generator_iterator.hpp> 

typedef boost::mt19937 base_generator_type; 
typedef boost::lagged_fibonacci19937 fibo_generator_type; 
typedef boost::uniform_int<> distribution_type; 
typedef boost::variate_generator<fibo_generator_type&, 
distribution_type> gen_type; 

     int 
random_number (int bits) 
{ 
     fibo_generator_type fibo_generator; 
     int max = pow(10, bits); 
     distribution_type dist(1, max); 

     gen_type uni(fibo_generator, dist); 
     return uni(); 

}    /* ----- end of function random_number ----- */ 

stdafx.hy

#include <iostream> 
#include <cstdlib> 
#include <cmath> 

using namespace std; 

cada vez que lo ejecutas, todos generan la misma secuencia numérica

como 77, 33,5, 22, ...

cómo utilizar el impulso: al azar correctamente?


eso es todo. pero tal vez un pequeño problema, como la siguiente:

parece sonido

get_seed(); for (;;) {cout << generate_random() << endl; } // is ok 

que genereate el mismo número aleatorio

int get_random() {get_seed();return generate_random();} for (;;) {cout << get_random() <<endl;} // output the same random number yet 

Respuesta

6

Es necesario sembrar el generador de números aleatorios por lo que doesn' Empieza desde el mismo lugar cada vez.

Dependiendo de lo que esté haciendo con los números, es posible que deba reflexionar sobre cómo elegir el valor de inicialización. Si necesita aleatoriedad de alta calidad (si genera claves criptográficas y las quiere bastante seguras), necesitará un buen valor de inicialización. Si esto fuera Posix, sugeriría/dev/random, pero parece que estás usando Windows, así que no estoy seguro de cuál sería una buena fuente de semillas.

Pero si no te importa una semilla predecible (para juegos, simulaciones, etc.), una semilla rápida y sucia es la marca de tiempo actual devuelta por el tiempo().

+0

Ya derecha. Si la semilla es la misma, el generador comenzará con el mismo número aleatorio cada vez – A9S6

+0

que sea.pero tal vez tenga un pequeño problema, como el siguiente: parece sonido get_seed(); para (;;) {cout << generate_random() << endl; } // está bien genera el mismo número aleatorio int get_random() {get_seed(); return generate_random();} para (;;) {cout << get_random() << endl;} // salida el mismo número aleatorio aún – mono

+0

genera una semilla cada vez que se llama a la función. contra el uso de la misma semilla cada vez que es la misma semilla? por qué obtengo la misma secuencia de números aleatorios de la manera anterior – mono

13

si desea que la secuencia de números aleatorios para cambiar cada vez que se ejecuta el programa, es necesario cambiar la semilla aleatoria inicializando con la hora actual, por ejemplo,

encontrará un ejemplo there, extracto:

/* 
* Change seed to something else. 
* 
* Caveat: std::time(0) is not a very good truly-random seed. When 
* called in rapid succession, it could return the same values, and 
* thus the same random number sequences could ensue. If not the same 
* values are returned, the values differ only slightly in the 
* lowest bits. A linear congruential generator with a small factor 
* wrapped in a uniform_smallint (see experiment) will produce the same 
* values for the first few iterations. This is because uniform_smallint 
* takes only the highest bits of the generator, and the generator itself 
* needs a few iterations to spread the initial entropy from the lowest bits 
* to the whole state. 
*/ 
generator.seed(static_cast<unsigned int>(std::time(0))); 
+0

eso es todo. pero tal vez tenga un pequeño problema, como el siguiente: parece sonido get_seed(); para (;;) {cout << generate_random() << endl; } // está bien genera el mismo número aleatorio int get_random() {get_seed(); return generate_random();} para (;;) {cout << get_random() << endl;} // salida el mismo número aleatorio aún – mono

+8

Prefiero inicializar el PRNG a 'std :: time (NULL) + getpid()'. Esto asegura que los binarios ejecutados uno después de otro, en rápida sucesión, tengan sus PRNG inicializados de manera diferente. – user1202136

+1

Para mayor "seguridad", el enfoque correcto debe ser inicializar el PRNG usando/dev/random (o el equivalente en [Windows] (https://en.wikipedia.org/wiki/Entropy_ (computing) #Windows).) – Avio

5

Si está ejecutando en un sistema 'nix, siempre puede intentar algo como esto;

int getSeed() 
{ 
    ifstream rand("/dev/urandom"); 
    char tmp[sizeof(int)]; 
    rand.read(tmp,sizeof(int)); 
    rand.close(); 
    int* number = reinterpret_cast<int*>(tmp); 
    return (*number); 
} 

supongo sembrar el generador de números aleatorios de esta manera es más rápido que la simple lectura del /dev/urandom (o /dev/random) para todas sus necesidades de números aleatorios.

+0

Esta es la idea correcta. Tenga en cuenta que en las versiones más nuevas de Boost, al menos, esto es abstraído para usted por 'random_device'. Como beneficio adicional, 'random_device' también debería implementarse en Windows. Desafortunadamente, si lo entiendo correctamente, no está implementado en BSD, porque BSD/dev/urandom no es realmente no determinista. Entonces, si desea la interoperabilidad de Linux y Windows, supongo que puede usar 'random_device' y si desea la interoperabilidad de Linux y BSD, puede usar la lectura explícita de/dev/urandom. Si quieres alguna otra combinación de interoperabilidad, ¡creo que estás solo! – Chinasaur

2

Puede usar la clase boost::random::random_device tal como está, o para sembrar su otro generador.

Usted puede obtener un número aleatorio de una sola vez fuera de él con un simple:

 
boost::random::random_device()() 

+0

Parece que devuelve un resultado de tipo 'unsigned int' (me preguntaba ... así que tuve que buscarlo). –

Cuestiones relacionadas