2011-04-07 58 views
16

He escrito un generador de números aleatorios simple en C. int l es el límite inferior y int u es el límite superior.srand (time (NULL)) no cambia el valor inicial lo suficientemente rápido

Funciona bien, sin embargo, tengo una pregunta con respecto a sembrarlo. Si tuviera que ejecutar esto en un bucle, time(NULL) no cambia el valor inicial lo suficientemente rápido para poder evitar obtener una serie consecutiva de números aleatorios que sean exactamente iguales.

Me pregunto cómo alguien más podría haber abordado este problema. Todos los ejemplos que he encontrado en línea usan time(NULL) como el generador de valores iniciales.

int generateRandom(int l, int u) 
{ 
    srand(time(NULL)); 

    int r = rand() % ((u - l) + 1); 
    r = l + r; 

    return r; 
} 

Si tuviera que ejecutar estas líneas de código uno al lado del otro, ambos Rand1 y Rand2 sería exactamente el mismo.

printf("Rand1 = %d\n", generateRandom(10, 46)); 
printf("Rand2 = %d\n", generateRandom(10, 46)); 
+8

¡Uf! ¡No mencione las variables como un simple 'l' sin adornos! Prefiero 'lb',' lower', 'lowbound', ... – pmg

Respuesta

19

srand(time(NULL)) se debe ejecutar exactamente una vez para iniciar el PRNG. Haz esto en Main cuando comience la aplicación.

Explicación:

A PRNG (Pseudo-Random Number Generator) genera una secuencia determinista de números que dependen del algoritmo utilizado. Un algoritmo dado siempre producirá la misma secuencia desde un punto de partida dado (semilla). Si no se siembra explícitamente el PRNG, generalmente comenzará desde la misma semilla predeterminada cada vez que se ejecute una aplicación, lo que resulta en la misma secuencia de números que se utiliza.

Para arreglar esto, necesita sembrar el PRNG usted mismo con un simiente diferente (para dar una secuencia diferente) cada vez que se ejecuta la aplicación. El enfoque habitual es usar time(NULL) que establece la semilla en función de la hora actual. Siempre que no inicie dos instancias de la aplicación en un segundo el uno del otro, se le garantizará una secuencia aleatoria diferente.

No es necesario sembrar la secuencia cada vez que desee un nuevo número aleatorio. Y no estoy seguro de esto, pero tengo la sensación de que, dependiendo del algoritmo PRNG que se use, la nueva siembra para cada nuevo número puede dar como resultado una aleatoriedad menor en la secuencia resultante.

+2

Al menos, resembrar no ayudará en la calidad, incluso si no duele. Lo cual hace, al menos si siembra desde 'tiempo (NULL)' cada vez. –

7

Semilla una vez al principio de la tubería principal. Si resembras demasiado rápido durante el mismo segundo, terminarás obteniendo los mismos números.

5

No lo siembre cada vez, solo al comienzo de su programa.

Además, muchos libros aconsejan no usar las funciones aleatorias estándar de C-lib. Si necesita buenos números pseudoaleatorios, hay un buen algoritmo en Press et al., Numerical Recipes, 3rd. Edición.

+0

Tenga cuidado con NR sin embargo, los términos de la licencia para el código en el libro son bastante onerosos, la edición que básicamente prohíbe cualquier tipo de control de versión o almacenamiento de archivos de red si lo escribe! – Flexo

4

Supongo que llama a la función generateRandom desde otra función, main o algo así.

Si declara la semilla dentro de la función, restablecerá la función. Al restablecer la función, aparecerán los mismos números varias veces, el mismo segundo.

Mover srand(time(NULL)); a la función principal resolverá el problema.

1

Si está usando procesos diferentes, utilizar (rand()+getpid())%range; lo uso para poner a prueba el mismo programa con valores aleatorios muchas veces por segundo (Si haces números de rand, salir del programa y ejecutar de nuevo muy rápido, los números serán la mismo)

4

srand((unsigned) time(NULL) * getpid());

produce un conjunto aleatorio más diversa (en OSX 10.8), incluyendo en las pruebas de ciclo cortos.

+0

Si tiene OS X 10.8 y le importa la aleatoriedad, debe usar 'arc4random()' o 'arc4random_uniform()'. – dreamlax

Cuestiones relacionadas