Generar números aleatorios eficazmente con rand()

última actualización el 28 de mayo de 2009, 02:43 por Carlos-vialfa
Publicado por Carlos-vialfa

Generar números aleatorios eficazmente con Rand()




Quizás te hayas podido dar cuenta que en C, utilizando 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;
}


Ejecutemos el programa y veamos el 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 numero 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. Puede ser obtenido, sobre 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 sintaxis siguiente funciona con gcc bajo Linux y la podrás encontrar con dev C++ bajo Windows.

#include <stdlib.h>
#include <stdio.h>

int rdtsc()
{
    __asm__ __volatile__("rdtsc");
}

int main()
{
    int i;
    for(i=0; i<5; i++)
    {
        srand(rdtsc());
        printf("%d\n", rand());
    }
    return 0;
}


Con este código, generaras 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.

PD: El artículo original fue escrito por kilian, contribuidor de CommentCaMarche
Mejores respuestas para « Generar números aleatorios eficazmente con rand() » en :
Generar números aleatorios eficazmente con Rand() Ver Generar números aleatorios eficazmente con Rand() Quizás te hayas podido dar cuenta que en C, utilizando la función rand() de la biblioteca estándar, se obtienen resultados decepcionantes, casi siempre los mismos. Por ejemplo, si deseamos...
Sed – Numerar las líneas VerNumerar las líneas Numerar las líneas (equivalente a "cat -n fichero.txt") sed = fichero.txt El inconveniente es que la numeración aparece en una línea aparte, no al lado de la línea. Para que aparezca al lado: sed = fichero.txt | sed...
Oracle – Generar estadísticas VerPara generar estadísticas relativas a tu base de datos, tan solo ejecuta el siguiente script: $ORACLE_HOME/rdbms/admin/utlbstat.sql Luego te aparecera informacion de utilidad. Activar la auditoría sobre un objeto Para activar la auditoría...
Descargar Driver de webcam General Electric Minicam Pro HO98067 VerDescarga completamente gratis el driver para tu Webcam General Electric Minicam Pro HO98067. Para Windows XP/2000/Me/98SE Guarda tu driver en una carpeta (crea una carpeta con nombre igual al modelo), para tenerlo siempre ubicado, cuando lo...
Memoria de acceso aleatorio (memoria RAM o PC) VerTipos de memoria de acceso aleatorio En términos generales, existen dos grandes categorías de memoria de acceso aleatorio: La memorias DRAM (Módulo de Acceso Aleatorio Dinámico), las cuales son menos costosas. Se utilizan principalmente para la...
Firewall VerFirewall Cada ordenador que se conecta a internet (y, básicamente, a cualquier red de ordenadores) puede ser víctima del ataque de un hacker. La metodología que generalmente usan los hackers consiste en analizar la red (mediante el envío aleatorio...
Términos y condiciones generales de uso VerTodos los derechos reservados - 2009 - Communitic International Objetivo Estos términos y condiciones generales se han formulado para definir el modo en el cual los servicios de la página Web Kioskea.net, de aquí en adelante "El servicio", están...