programming for examples dummies crossover algorithms c++ c random srand

c++ - for - genetic algorithms examples



¿Cuál es la diferencia entre srand(1) y srand(0) (7)

Al leer las páginas del manual, todos afirman que "Si no se proporciona un valor de inicialización, la función rand () se inicializa automáticamente con un valor de 1". Probablemente esta sea la razón por la que la página de referencia a la que se vincula indica que la inicialización con 1 restablece el estado.

El hecho de que ocurra lo mismo para la inicialización tanto con 0 como con 1 es muy probablemente dependiente de la implementación, y no debe contarse con que suceda en todas las plataformas.

Acabo de descubrir el modo difícil en que srand(1) restablece el PRNG de C (++) al estado antes de cualquier llamada a srand (como se define en la reference ). Sin embargo, la semilla 0 parece hacer lo mismo, o el estado antes de cualquier llamada a srand parece usar la semilla 0. ¿Cuál es la diferencia entre esas dos llamadas o cuál es la razón por la que hacen lo mismo?

Por ejemplo este código ( ejecutar en Ideone )

#include <stdio.h> #include <stdlib.h> int main() { for (int seed = 0; seed < 4; seed++ ) { printf( "Seed %d:", seed); srand( seed ); for(int i = 0; i < 5; i++ ) printf( " %10d", rand() ); printf( "/n"); } return 0; }

devoluciones

Seed 0: 1804289383 846930886 1681692777 1714636915 1957747793 Seed 1: 1804289383 846930886 1681692777 1714636915 1957747793 Seed 2: 1505335290 1738766719 190686788 260874575 747983061 Seed 3: 1205554746 483147985 844158168 953350440 612121425


Como lo hace glibc:

alrededor de la línea 181 de glibc / stdlib / random_r.c , dentro de la función __srandom_r

/* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */ if (seed == 0) seed = 1;

Pero así es como Glibc lo hace. Depende de la implementación de la librería estándar de C.


La función srand () usa el argumento como semilla para una nueva secuencia de números pseudoaleatorios que serán devueltos por las llamadas subsiguientes a rand (). Si se llama a srand () con el mismo valor semilla, se repetirá la secuencia de números pseudoaleatorios. Si se llama a rand () antes de que se realicen llamadas a srand (), se generará la misma secuencia que cuando se llama por primera vez a srand () con un valor semilla de 1.

Tal vez útil: http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html


La razón por la que se especifica 1 es porque algunos generadores de números aleatorios se atascarán en cero si la semilla se establece en cero. Por ejemplo, los registros de desplazamiento y los tipos congruentes multiplicativos, es decir, r(n+1) = (A * r(n))mod M

Muchas implementaciones de C usan la Congruencia lineal r(n+1) = (A * r(n) + B) mod M , B <> 0 que no se atascan.


Ni los estándares de C ni de C ++ dicen mucho sobre los aspectos específicos de la implementación de rand() y srand() . Los detalles se dejan casi totalmente a cargo del implementador. El estándar C requiere que:

Si se llama a srand con el mismo valor semilla, se repetirá la secuencia de números pseudoaleatorios. Si se llama a rand antes de que se realicen llamadas a srand, se generará la misma secuencia que cuando se llama a srand por primera vez con un valor semilla de 1.

pero no contiene ningún requisito de que diferentes semillas deban producir diferentes secuencias. Aparentemente, en tu sistema, las semillas de cero y una tienen el mismo efecto. Supongo que esto es para proporcionar compatibilidad hacia atrás con algún software que espera que srand(0) restablezca el PRNG a su estado inicial.


Probablemente es un detalle de implementación. El estándar obliga a que la semilla aleatoria 1 sea especial, y el registro interno de su algoritmo generador aleatorio específico es probablemente cero inicializado, lo que causa la misma secuencia aleatoria para la semilla (0) y la semilla (1). Incluso apostaría a que la primera línea de su implementación de srand () se ve así:

if ( seed == 1 ) seed = 0;

forzar el comportamiento conforme a la norma.

En general, los generadores de números aleatorios para rand () y srand () no están obligados a dar diferentes secuencias para diferentes semillas, sino la misma secuencia para la misma semilla. Entonces, no confíes en las diferentes semillas que generan diferentes secuencias aleatorias , y deberías estar bien. Si no, bienvenido a la diversión específica de la implementación.


Si se establece semilla en 1, el generador se reinicializa a su valor inicial y produce los mismos valores que antes de cualquier llamada a rand o srand. Tomado de la referencia reference