2010-07-01 32 views
8

gcc 4.4.4 c89usando rand para generar un número aleatorio

Estoy usando el siguiente código. Sin embargo, sigo obteniendo el mismo número:

size_t i = 0; 

    for(i = 0; i < 3; i++) { 
     /* Initialize random number */ 
     srand((unsigned int)time(NULL)); 
     /* Added random number (simulate seconds) */ 
     add((rand() % 30) + 1); 
    } 

Me gustaría obtener 0 a 30 devuelto. Sin embargo, la última vez que ejecuté esto obtuve 17 tres veces.

Muchas gracias,

+2

posible duplicado de [función de número aleatorio se fallando] (http: // stackoverflow.com/questions/1068350/random-number-function-is-foqueado) –

Respuesta

22

Estás sembrando el interior del bucle (con el mismo valor debido a la rapidez con que se ejecutará el bucle), lo que hace que el número aleatorio generado a ser el mismo cada vez.

tiene que mover su función de semilla fuera del bucle:

/* Initialize random number */ 
srand((unsigned int)time(NULL)); 

for(i = 0; i < 3; i++) { 
    /* Added random number (simulate seconds) */ 
    add((rand() % 30) + 1); 
} 
9

Es necesario llamar a srand sólo una vez, al comienzo de su programa.

srand inicializa el generador de números pseudoaleatorios utilizando el tiempo en segundos. Si lo inicializa con un número particular, siempre obtendrá la misma secuencia de números. Es por eso que generalmente desea inicializarlo al principio utilizando el tiempo (para que la semilla sea diferente cada vez que ejecuta el programa) y luego use solo rand para generar números que parecen aleatorios.

En su caso, el tiempo no cambia de iteración a iteración, ya que su resolución es de solo 1 segundo, por lo que siempre obtendrá el primer número de la secuencia pseudoaleatoria, que siempre es la misma.

+1

¿Es realmente cierto que 'necesita llamar a Srand una sola vez, al comienzo de su programa? Quiero decir, creo que si uno necesita deberían llamar '' srand' cada vez que necesiten cambiar la semilla del generador de números aleatorios y obtener una secuencia diferente de números aleatorios. –

+0

Es cierto para esta pieza de código en particular;). Por supuesto, puede llamarlo siempre que quiera cambiar la semilla por alguna razón; no está prohibido. –

+0

@skwllsp y eso usualmente solo una vez _per request_! – alexanderpas

4

Debe hacer srand((unsigned int)time(NULL)) solo una vez antes del ciclo.

2

Es completamente posible que las 3 veces 17 sigan siendo completamente aleatorias.

Hay aproximadamente 1 en 10 posibilidades de obtener dos números iguales cuando se usa un rango de 1-30 y tres selecciones. (Esto se debe a birthday problem)

Ahora, obtener tres los mismos resultados tiene una capacidad de propagación de 1 en 900 con el mismo rango.

es posible que desee leer más antecedentes sobre la Semilla analysis page of random.org

+0

En este caso (incluso si no fue un error de codificación) obteniendo dos 17s en una fila no tiene nada que ver con el problema del cumpleaños. Suponer que cada número aleatorio es independiente, calcular la probabilidad de obtener dos 17 seguidos sería 1/30 * 1/30 o 1/900. Para tres sería 1/30 * 1/30 * 1/30 o 1/27000. – MarkD

+0

pero te olvidas de que hay 30 posibilidades diferentes de obtener tres números iguales. 1/27000 * 30 = 1/900 – alexanderpas

+0

ahora, para los dos lo mismo ... en realidad hay tres combinaciones XYX, XXY e YXY con 30 posibilidades cada una. 1/900 * 30 = 1/30 * 3 = 3/30 = 1/10 – alexanderpas

1

para el generador de números pseudo aleatoria debe ser llamado una sola vez fuera del bucle. Usar el tiempo como semilla es algo bueno. Sin embargo, todavía hay una posibilidad de obtener el mismo número aleatorio.

1

Sugiero usar también la llamada al sistema gettimeofday() para recuperar la semilla que se utilizará para alimentar a srand().

Algo así como

 

struct timeval tv; 
... 
gettimeofday(&tv, NULL); 
srand(tv.tv_usec); 
... 
 

Este enfoque puede agregar más entropía en su código de generación de números pseudo. mi humilde opinión, por supuesto

Ciao Ciao

Cuestiones relacionadas