rand () genera el mismo número, ¡incluso con srand (time (NULL)) en mi main!

Entonces, estoy tratando de crear un vector aleatorio (piense en geometría, no en una matriz expandible), y cada vez que llamo a mi función vectorial aleatoria obtengo el mismo valor x, aunque y y z son diferentes.

int main () { srand ( (unsigned)time(NULL)); Vector a; a.randvec(); cout << a << endl; return 0; } 

usando la función

 //random Vector template  void Vector::randvec() { const int min=-10, max=10; int randx, randy, randz; const int bucket_size = RAND_MAX/(max-min); do randx = (rand()/bucket_size)+min; while (randx = max); x = randx; do randy = (rand()/bucket_size)+min; while (randy = max); y = randy; do randz = (rand()/bucket_size)+min; while (randz = max); z = randz; } 

Por alguna razón, randx siempre devolverá 8, mientras que los otros números parecen estar siguiendo la (pseudo) aleatoriedad perfectamente. Sin embargo, si puse la llamada para definir, por ejemplo, Randy antes de Randx, Randy siempre devolverá 8.

¿Por qué mi primer número aleatorio siempre es 8? ¿Estoy sembrando incorrectamente?

El problema es que el generador de números aleatorios está siendo sembrado con valores muy cercanos: cada ejecución del progtwig solo cambia el valor de retorno del tiempo () en una pequeña cantidad, ¡quizás 1 segundo, tal vez ni siquiera uno! El generador de números aleatorios estándar, bastante pobre, utiliza estos valores iniciales similares para generar números aleatorios iniciales aparentemente idénticos. Básicamente, necesita un generador inicial de semillas mejor que time () y un generador de números aleatorios mejor que rand ().

El algoritmo de bucle real utilizado es, creo, levantado de Acelerado C ++ y está destinado a producir una mejor dispersión de números sobre el rango requerido que decir usando el operador de mod. Pero no puede compensar que siempre se le dé (efectivamente) la misma semilla.

No veo ningún problema con su srand() , y cuando traté de ejecutar código extremadamente similar, no repetidamente obtuve el mismo número con el primer rand() . Sin embargo, sí noté otro problema posible.

 do randx = (rand()/bucket_size)+min; while (randx <= min && randx >= max); 

Esta línea probablemente no hace lo que pretendías. Mientras min < max (y siempre debe ser así), es imposible que randx sea ​​menor o igual que min y mayor que o igual a max . Además, no necesita bucle en absoluto. En cambio, puede obtener un valor entre mínimo y máximo usando:

 randx = rand() % (max - min) + min; 

También para mencionar, incluso puede deshacerse de esa extraña variable bucket_size y usar el siguiente método para generar números de bucket_size inclusive:

 srand ((unsigned)time(NULL)); const int a = -1; const int b = 1; int x = rand() % ((b - a) + 1) + a; int y = rand() % ((b - a) + 1) + a; int z = rand() % ((b - a) + 1) + a; 

Una solución rápida simple es llamar al rand varias veces después de la siembra.

 int main () { srand ( (unsigned)time(NULL)); rand(); rand(); rand(); Vector a; a.randvec(); cout << a << endl; return 0; } 

Para explicar mejor, la primera llamada a rand () en cuatro ejecuciones secuenciales de un progtwig de prueba dio el siguiente resultado:

 27592 27595 27598 27602 

¿Te das cuenta de lo similares que son? Por ejemplo, si divide rand() por 100, obtendrá el mismo número 3 veces seguidas. Ahora eche un vistazo al segundo resultado de rand () en cuatro ejecuciones secuenciales:

 11520 22268 248 10997 

Esto se ve mucho mejor, ¿no? Realmente no veo ninguna razón para los votos abajo.

Tuve el mismo problema exactamente. Lo arreglé moviendo la llamada a srand () para que solo se llamara una vez en mi progtwig (anteriormente lo había estado sembrando en la parte superior de una llamada de función). Realmente no entiendo los tecnicismos, pero fue un problema resuelto.

Su implementación, a través de la división de enteros, ignora los 4-5 bits más pequeños del número aleatorio. Debido a que su RNG se inserta con la hora del sistema, el primer valor que obtenga solo cambiará (en promedio) cada 20 segundos.

Esto debería funcionar:

 randx = (min) + (int) ((max - min) * rand() / (RAND_MAX + 1.0)); 

dónde

 rand() / (RAND_MAX + 1.0) 

es un valor doble aleatorio en [0, 1) y el rest solo lo está cambiando.