Saltar al contenido

srand(): ¿por qué llamarlo solo una vez?

Hola, tenemos la solución a lo que estabas buscando, deslízate y la hallarás un poco más abajo.

Solución:

Eso depende de lo que estés tratando de lograr.

La aleatorización se realiza como una función que tiene un valor inicial, a saber la semilla.

Entonces, para la misma semilla, siempre obtendrás la misma secuencia de valores.

Si intenta establecer la semilla cada vez que necesita un valor aleatorio, y la semilla es el mismo número, siempre obtendrá el mismo valor “aleatorio”.

La semilla generalmente se toma de la hora actual, que son los segundos, como en time(NULL)por lo que si siempre configura la semilla antes de tomar el número aleatorio, obtendrá el mismo número siempre que llame al combo srand/rand varias veces en el mismo segundo.

Para evitar este problema, srand se establece solo una vez por aplicación, porque es dudoso que dos de las instancias de la aplicación se inicialicen en el mismo segundo, por lo que cada instancia tendrá una secuencia diferente de números aleatorios.

Sin embargo, existe una pequeña posibilidad de que ejecute su aplicación (especialmente si es corta, o una herramienta de línea de comandos o algo así) muchas veces en un segundo, luego tendrá que recurrir a otra forma de elegir una seed (a menos que usted acepte la misma secuencia en diferentes instancias de la aplicación). Pero como dije, eso depende del contexto de uso de su aplicación.

Además, es posible que desee intentar aumentar la precisión a microsegundos (minimizando la posibilidad de la misma semilla), requiere (sys/time.h):

struct timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);

Los números aleatorios son en realidad pseudoaleatorios. Primero se establece una semilla, de la cual cada llamada de rand obtiene un número aleatorio y modifica el estado interno y este nuevo estado se usa en el siguiente rand llamar para obtener otro número. Debido a que se usa una cierta fórmula para generar estos “números aleatorios”, por lo tanto, se establece un cierto valor de semilla después de cada llamada a rand devolverá el mismo número de la llamada. Por ejemplo srand (1234); rand (); devolverá el mismo valor. Inicializar una vez el estado inicial con el valor semilla generará suficientes números aleatorios ya que no establece el estado interno con srandlo que hace que los números sean más probables de ser aleatorios.

Generalmente usamos el time (NULL) devolvió el valor de los segundos al inicializar el valor inicial. di el srand (time (NULL)); está en un bucle. Luego, el ciclo puede iterar más de una vez en un segundo, por lo tanto, la cantidad de veces que el ciclo itera dentro del ciclo en un segundo rand la llamada en el bucle devolverá el mismo “número aleatorio”, que no se desea. Inicializarlo una vez al inicio del programa establecerá la semilla una vez, y cada vez rand se llama, se genera un nuevo número y se modifica el estado interno, por lo que la próxima llamada rand devuelve un número que es lo suficientemente aleatorio.

Por ejemplo, este código de http://linux.die.net/man/3/rand:

static unsigned long next = 1;
/* RAND_MAX assumed to be 32767 */
int myrand(void) 
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);

void mysrand(unsigned seed) 
    next = seed;

el estado interno next se declara como global. Cada myrand call modificará el estado interno y lo actualizará, y devolverá un número aleatorio. Cada llamada de myrand tendrá una diferente next Por lo tanto, el método devolverá los diferentes números en cada llamada.

mira el mysrand implementación; simplemente establece el valor inicial que pasa a next. Por lo tanto, si establece el next valora lo mismo cada vez antes de llamar rand devolverá el mismo valor aleatorio, debido a que se le aplicó una fórmula idéntica, lo cual no es deseable, ya que la función está hecha para ser aleatoria.

Pero dependiendo de sus necesidades, puede establecer la semilla en un valor determinado para generar la misma “secuencia aleatoria” en cada ejecución, por ejemplo, para un punto de referencia u otro.

Respuesta corta: llamar srand() es no como “tirar los dados” para el generador de números aleatorios. Tampoco es como barajar una baraja de cartas. En todo caso, es más como cortar una baraja de cartas.

Piensa en esto, de esta manera. rand() reparte de una gran baraja de cartas, y cada vez que lo llama, todo lo que hace es elegir la siguiente carta de la parte superior de la baraja, darle el valor y devolver esa carta al fondo de la baraja. (Sí, eso significa que la secuencia “aleatoria” se repetirá después de un tiempo. Es un muy gran baraja, sin embargo: típicamente 4,294,967,296 cartas).

Además, cada vez que se ejecuta su programa, se compra un nuevo paquete de cartas en la tienda del juego, y cada nuevo paquete de cartas siempre tiene la misma secuencia. Entonces, a menos que haga algo especial, cada vez que se ejecute su programa, obtendrá exactamente los mismos números “aleatorios” de rand().

Ahora, podrías decir: “Está bien, entonces, ¿cómo barajo la baraja?” Y la respuesta, al menos en lo que respecta a rand y srand están preocupados- es que no hay forma de barajar las cartas.

entonces que hace srand ¿hacer? Basado en la analogía que he estado construyendo aquí, llamando srand(n) es básicamente como decir, “cortar el mazo n cartas desde arriba”. Pero espera, una cosa más: en realidad es comience con otra plataforma nueva y córtela n cartas desde arriba.

Así que si llamas srand(n), rand(), srand(n), rand()…, con el mismo n cada vez, no solo obtendrá una secuencia no muy aleatoria, en realidad obtendrá el mismo número de rand() cada vez. (Probablemente no sea el mismo número que le diste a srandpero el mismo número de vuelta de rand una y otra vez.)

Así que lo mejor que puedes hacer es cortar el mazo una vezes decir, llamar srand() una vez, al comienzo de su programa, con un n eso es razonablemente aleatorio, por lo que comenzará en un lugar aleatorio diferente en el mazo grande cada vez que se ejecute su programa. Con rand()eso es realmente lo mejor que puedes hacer.

[P.S. Yes, I know, in real life, when you buy a brand-new deck of cards it’s typically in order, not in random order. For the analogy here to work, I’m imagining that each deck you buy from the game shop is in a seemingly random order, but the exact same seemingly-random order as every other deck of cards you buy from that same shop. Sort of like the identically shuffled decks of cards they use in bridge tournaments.]

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *