¿Por qué siempre obtengo la misma secuencia de números aleatorios con rand ()?

Esta es la primera vez que bash números aleatorios con C (extraño a C #). Aquí está mi código:

int i, j = 0; for(i = 0; i <= 10; i++) { j = rand(); printf("j = %d\n", j); } 

con este código, obtengo la misma secuencia cada vez que ejecuto el código. Pero genera diferentes secuencias aleatorias si agrego srand(/*somevalue/*) antes del ciclo for . ¿Alguien puede explicar por qué?

Tienes que sembrarlo Sembrarlo con el tiempo es una buena idea:

srand()

 #include  #include  #include  int main () { srand ( time(NULL) ); printf ("Random Number: %d\n", rand() %100); return 0; } 

Obtienes la misma secuencia porque rand () se siembra automáticamente con el valor a 1 si no llamas a srand ().

Editar

Debido a los comentarios

rand() devolverá un número entre 0 y RAND_MAX (definido en la biblioteca estándar). El uso del operador de módulo ( % ) proporciona el rest de la división rand()/100 . Esto obligará al número aleatorio a estar dentro del rango 0-99. Por ejemplo, para obtener un número aleatorio en el rango de 0-999, aplicaríamos rand()%1000 .

rand () devuelve números pseudoaleatorios . Genera números basados ​​en un algoritmo dado. El punto de partida de ese algoritmo es siempre el mismo, por lo que verá la misma secuencia generada para cada invocación. Esto es útil cuando necesita verificar el comportamiento y la coherencia de su progtwig.

Puede establecer la “semilla” del generador aleatorio con la función srand (solo llame srand una vez en un progtwig) Una forma común de obtener diferentes secuencias del generador rand () es establecer la semilla a la hora actual o la identificación de el proceso:

srand (tiempo (NULL)); o srand (getpid ()); al comienzo del progtwig.

Generar aleatoriedad real es muy difícil para una computadora, pero para el trabajo práctico no relacionado con cifrado, un algoritmo que intente distribuir de manera uniforme las secuencias generadas funciona bien.

Para citar de hombre rand :

La función srand () establece su argumento como la semilla de una nueva secuencia de enteros pseudoaleatorios que será devuelta por rand (). Estas secuencias son repetibles llamando a srand () con el mismo valor inicial.

Si no se proporciona ningún valor de inicialización, la función rand () se inicializa automáticamente con un valor de 1.

Entonces, sin valor inicial, rand () asume que la semilla es 1 (cada vez en su caso) y con el mismo valor inicial, rand () producirá la misma secuencia de números.

Si recuerdo la cita del trabajo seminal de Knuth “El arte de la progtwigción de computadoras” al comienzo del capítulo sobre Generación aleatoria de números, dice así:

“Cualquiera que intente generar números aleatorios por medios matemáticos está técnicamente hablando en estado de pecado”.

En pocas palabras, los generadores de números aleatorios en stock son algoritmos matemáticos y 100% predecibles. Esto es realmente una buena cosa en muchas situaciones, donde una secuencia repetible de números “aleatorios” es deseable, por ejemplo para ciertos ejercicios estadísticos, donde no se desea el “bamboleo” en resultados que los datos verdaderamente aleatorios presentan gracias a efectos de agrupamiento.

Aunque capturar fragmentos de datos “aleatorios” del hardware de la computadora es una segunda alternativa popular, tampoco es realmente aleatoria, aunque cuanto más complejo sea el entorno operativo, más posibilidades de aleatoriedad o al menos imprevisibilidad.

Los generadores de datos verdaderamente aleatorios tienden a buscar fonts externas. La decadencia radiactiva es un favorito, como lo es el comportamiento de los cuásares. Cualquier cosa cuyas raíces estén en efectos cuánticos es efectivamente aleatoria, para gran disgusto de Einstein.

Aquí hay muchas respuestas, pero nadie parece haber explicado por qué Rand () siempre genera la misma secuencia con la misma semilla, o incluso lo que la semilla realmente está haciendo. Así que aquí va.

La función rand () mantiene un estado interno. Conceptualmente, podría pensar en esto como una variable global de algún tipo llamada rand_state. Cada vez que llamas a rand (), hace dos cosas. Utiliza el estado existente para calcular un nuevo estado y usa el nuevo estado para calcular un número que le devolverá:

 state_t rand_state = INITIAL_STATE; state_t calculate_next_state(state_t s); int calculate_return_value(state_t s); int rand(void) { rand_state = calculate_next_state(rand_state); return calculate_return_value(rand_state); } 

Ahora puede ver que cada vez que llama a rand (), hará que rand_state avance un paso a lo largo de una ruta predeterminada. Los valores aleatorios que ve se basan simplemente en el lugar en el que se encuentra a lo largo de esa ruta, por lo que también van a seguir una secuencia predeterminada.

Ahora aquí es donde entra srand (). Te permite saltar a un punto diferente en la ruta:

 state_t generate_random_state(unsigned int seed); void srand(unsigned int seed) { rand_state = generate_random_state(seed); } 

Los detalles exactos de state_t, calculate_next_state (), calculate_return_value () y generate_random_state () pueden variar de plataforma a plataforma, pero generalmente son bastante simples.

Puede ver que cada vez que se inicia el progtwig, rand_state va a comenzar en INITIAL_STATE (que es equivalente a generate_random_state (1)), por lo que siempre obtendrá la misma secuencia si no usa srand ().

Los generadores de números aleatorios no son en realidad aleatorios, les gusta que la mayoría del software sea completamente predecible. Lo que hace rand es crear un número pseudoaleatorio diferente cada vez que se lo llame Uno que parece ser aleatorio. Para usarlo correctamente, debe darle un punto de partida diferente.

 #include  #include  #include  int main () { /* initialize random seed: */ srand ( time(NULL) ); printf("random number %d\n",rand()); printf("random number %d\n",rand()); printf("random number %d\n",rand()); printf("random number %d\n",rand()); return 0; } 

Esto es de http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html#rand :

Declaración:

 void srand(unsigned int seed); 

Esta función siembra el generador de números aleatorios utilizado por la función rand. Sembrar srand con la misma semilla hará que rand devuelva la misma secuencia de números pseudoaleatorios. Si no se llama srand, rand actúa como si se hubiera llamado a srand (1).

rand () devuelve el siguiente número (pseudo) aleatorio de una serie. Lo que sucede es que tienes la misma serie cada vez que se ejecuta (valor predeterminado ‘1’). Para iniciar una nueva serie, debe llamar a srand () antes de comenzar a llamar a rand ().

Si quieres algo al azar cada vez, puedes intentar:

 srand (time (0)); 

llame a srand(sameSeed) antes de llamar a rand() . Más detalles aquí .

Siembra del rand()

 void srand (unsigned int seed) 

Esta función establece la semilla como la semilla para una nueva serie de números pseudoaleatorios. Si llama a rand antes de que se establezca una semilla con srand, usa el valor 1 como semilla predeterminada.

Para producir una serie pseudoaleatoria diferente cada vez que se ejecuta su progtwig, haga srand (time (0))

Ninguno de ustedes está respondiendo su pregunta.

con este código obtengo la misma sequance cada vez que el código, pero genera secuencias aleatorias si agrego srand (/ somevalue /) antes del ciclo for. ¿alguien puede explicar por qué?

Según lo que me dijo mi profesor, se usa si quieres asegurarte de que tu código se está ejecutando correctamente y para ver si hay algún problema o si puedes cambiar algo.

Por cierto: el hecho de que rand NO sea aleatorio (PRNG = PSEUDO Random Number Generator, donde pseudo es la palabra clave!) Puede ser muy útil.

Si el mismo algoritmo se usa en computadoras a través de una red, y si algunos datos (por ejemplo, estado del juego) se calculan usando números ‘aleatorios’, y si el código en todas las máquinas se sincroniza de tal manera que se llama al rand en el mismo lugar / tiempo de todos los clientes, entonces puede reducir la carga de red regenerando datos / eventos / lo que sea localmente.

Pseudo-aleatorio es una cosa encantadora. 🙂


PD: si alguna vez confías en que rand (om) se sincroniza, sin embargo, debes codificar tu propia implementación; de lo contrario, la plataforma y otras diferencias arruinarán tu diversión. 🙂