¿Por qué Rand () produce la misma secuencia de números en cada carrera?

Cada vez que ejecuto un progtwig con rand() me da los mismos resultados.

Ejemplo:

 #include  #include  using namespace std; int random (int low, int high) { if (low > high) return high; return low + (rand() % (high - low + 1)); } int main (int argc, char* argv []) { for (int i = 0; i < 5; i++) cout << random (2, 5) << endl; } 

Salida:

 3 5 4 2 3 

Cada vez que ejecuto el progtwig, muestra los mismos números cada vez. ¿Hay alguna forma de evitar esto?

La semilla para el generador de números aleatorios no está establecida.

Si llama a srand (time (NULL)), obtendrá más resultados aleatorios:

 #include  #include  #include  using namespace std; int main() { srand(time(NULL)); cout << rand() << endl; return 0; } 

La razón es que un número aleatorio generado a partir de la función rand () no es realmente aleatorio. Simplemente es una transformación. Wikipedia ofrece una mejor explicación del significado del generador de números pseudoaleatorios: generador determinístico de bits aleatorios. Cada vez que llamas a rand () toma la semilla y / o los últimos números aleatorios generados (el estándar C no especifica el algoritmo utilizado, aunque C ++ 11 tiene facilidades para especificar algunos algoritmos populares), ejecuta un operación matemática en esos números, y devuelve el resultado. Entonces, si el estado de la semilla es el mismo cada vez (como lo es si no llamas a srand con un número verdaderamente aleatorio), siempre obtendrás los mismos números "aleatorios".

Si quieres saber más, puedes leer lo siguiente:

http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/

http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/

Si llama a rand() sin llamar primero a srand() , actuará como si hubiera llamado a srand(1) implícitamente. El bit relevante del estándar C99 7.20.2.2 The srand function (en la que se basa C99 7.20.2.2 The srand function ) establece:

Si se llama rand antes de realizar cualquier llamada a srand, se generará la misma secuencia que cuando se llama primero a srand con un valor inicial de 1.

En otras palabras, obtendrás la misma secuencia cada vez. Puedes cambiar tu main en:

 int main (int argc, char* argv []) { srand (time (0)); // needs ctime header. for (int i = 0; i < 5; i++) cout << random (2, 5) << endl; wait (); } 

para arreglar esto, suponiendo que no lo ejecute más de una vez por segundo.

Como se mencionó, necesitará el encabezado ctime para esto. También deberías tirar en cstdlib ya que es donde viven rand y srand . También suele ser una buena idea usar los encabezados cXXX lugar de los XXX.h ( cmath lugar de math.h , por ejemplo).

Entonces, habiendo realizado todos esos cambios (y usando espacios de nombres explícitos, que prefiero, aunque otros no), terminaría con:

 #include  #include  #include  #include  void wait () { int e; std::cin >> e; } int random (int low, int high) { if (low > high) return high; return low + (std::rand() % (high - low + 1)); } int main (int argc, char* argv []) { std::srand (std::time (0)); for (int i = 0; i < 5; i++) std::cout << random (2, 5) << '\n'; wait (); } 

que da una secuencia diferente cada vez que lo ejecuto, por algunas veces de todos modos. Obviamente, hay un límite estricto sobre cuándo se repetirán los datos (solo hay 4 5 posibilidades) y la naturaleza "aleatoria" de la salida significa que también puede repetirse antes de esa fecha 🙂

Esa es una característica de la función rand() .

Lo que tienes no es un generador de números aleatorios, sino más estrictamente un “generador de números aleatorios pseudo” . Ser capaz de reproducir las mismas secuencias aleatorias para la misma semilla (semillas usando la función srand(x) ) puede ser importante para reproducir errores o para preservar el estado en las ejecuciones del progtwig.

Personalmente, utilizo esta función para poder pausar / persistir los procesos de representación en un renderizador de terreno basado en monte carlo . Un buen efecto secundario es que puede garantizar diferentes experimentos de monte carlo en diferentes máquinas y, por lo tanto, generar resultados garantizados diferentes que luego se pueden reducir en un paso final a un resultado final de mayor calidad (por supuesto, puede reutilizarlo más adelante). este resultado final de mayor calidad para producir resultados de mayor calidad).

Sin embargo, tenga en cuenta que ni C ni C ++ definen la secuencia numérica de rand() . Entonces, si necesita secuencias garantizadas en todas las plataformas, utilice uno de los nuevos generadores de números aleatorios de C ++ 11 (por ejemplo, un tornado mersenne ), haga lo propio (algunos generadores son casi triviales, porque la mayoría confía en un comportamiento de desbordamiento específico su implementación podría no ser trivial), o usar un componente de un tercero (por ejemplo, boost :: random).

Necesitas sembrar el generador de números aleatorios (mira la función ‘srand’). Suponiendo que no está haciendo criptografía, entonces sembrarlo con la salida de ‘tiempo’ es probablemente lo suficientemente bueno.

use randomize (). Genera automáticamente el valor. O si desea usar rand (), puede sembrar usando srand (seedvalue); el valor de la semilla puede ser similar al tiempo del sistema … eso le dará diferentes números aleatorios cada vez

En realidad, obtienes números aleatorios de psuedo. Para hacerlos “más aleatorios”, puedes sembrar el generador de números aleatorios usando algo que “cambie” (más comúnmente la hora actual).