Generar números aleatorios eficazmente con la función rand()
Quizás te hayas podido dar cuenta que en
C, al utilizar la función
rand() de la biblioteca estándar, se obtienen resultados decepcionantes, casi siempre los mismos.
Por ejemplo, si deseamos generar 5 números aleatorios uno después de otro:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i;
for(i=0; i<5; i++)
{
printf("%d\n", rand());
}
return 0;
}
Ejecutamos el programa y obtenemos este resultado:
41
18467
6334
26500
19169
Los resultados son significativamente diferentes, pero si volvemos a ejecutar el programa, tendremos la misma serie de números.
Para modificar el comportamiento del generador de números aleatorios, podemos modificar la variable sobre la que se basa para realizar los cálculos. A esto se le llama
seed o semilla.
Esta semilla se modifica con la función
srand():
srand(valor de la semilla)
Necesitamos un número que no podamos predecir fácilmente y que varíe de un instante a otro. Por ejemplo, puedes tomar el número de ciclos utilizados por tu procesador desde el inicio. Este puede ser obtenido, en procesadores x86 (Intel, Amd etc...), con el comando ensamblador
rdtsc. La escritura de una función
rdtsc() llamando a este comando de ensamblador podrá facilitarte las cosas. La siguiente sintaxis funciona con
gcc en Linux y la puedes encontrar con
dev C++ en Windows:
#include <stdlib.h>
#include <stdio.h>
int rdtsc()
{
__asm__ __volatil__("rdtsc");
}
int main()
{
int i;
for(i=0; i<5; i++)
{
srand(rdtsc());
printf("%d\n", rand());
}
return 0;
}
Con este código, generarás números aleatorios más eficaces.
Nota: Esta solución funciona únicamente con los procesadores x86.
También evita activar optimizaciones en el compilador (option-O1,-O2-O3 etc ...), cuando utilices la función
rdtsc.