Entradas etiquetadas como ‘srand()’

Generando números aleatorios en C y C++

Por que nunca esta por demás…

Primero que nada déjenme decirles que el lenguaje C incorpora dos funciones [rand() y srand()] las cuales son pseudo generadoras de números aleatorios; que quiero decir con “pseudo” , pues que en realidad no generan números aleatorios, si no que siguen un algoritmo, que muestran el resultado de un conjunto de operaciones (“numero aleatorio”) ; que al final de cuentas puede ser predecido teniendo dicho algoritmo.

Función rand()

Hablemos de la función rand() esta genera un numero aleatorio en el rango de 0 y 32767 (solo enteros) ; para obtener estos números el algoritmo de la función rand() parte de un “numero semilla” , quiero decir un numero inicial al cual somete a un conjunto de operaciones para así generar los números “aleatorios”, lo único malo de esta función es que siempre que queramos generar números aleatorios este algoritmo siempre partera de la misma semilla y realizara las mismas operaciones, por lo que obtendremos los mismos números aleatorios una y otra vez… sin importar las veces que ejecutemos el programa.

A continuación un ejemplo:

   1: #include <iostream.h>

   2: #include <stdlib.h>

   3: //Dentro de stdlib.h encontramos la funcion rand()

   4: #include <conio.h>

   5:  

   6: int main(){

   7:  

   8: long int aleatorio=0;

   9:  

  10: cout<<"Programa que genera numeros aleatorios con la funcion
rand()"
<<endl;

  11: aleatorio = rand();

  12: cout<<"El numero aleatorio generado es: "<<aleatorio <<endl;

  13: cout<<"El numero generado se encuentra en un rango del 0 al "<< RAND_MAX <<endl;

  14: getch();

  15:  

  16: }

La función rand() se encuentra en la librería stdlib.h, la palabra reservada RAND_MAX -> regresa el valor máximo de la función rand().

Hasta aquí creo que todo simple… empezamos con la emoción al momento que queremos un numero aleatorio entre un rango personalizado, por ejemplo del 0 al 5:

   1: #include <iostream.h>

   2: #include <stdlib.h>

   3: #include <conio.h>

   4:  

   5: int main(){

   6: long int aleatorio=0;

   7:  

   8: cout<<"Programa que genera numeros aleatorios de rango 0 a 5"<<endl;

   9:  

  10: aleatorio = rand() % 6;

  11: cout<<"El numero aleatorio generado es: "<<aleatorio <<endl;

  12: getch();

  13: }

Estamos utilizando el operador modulo (%) que es el residuo de una división, para delimitar el rango de la variable “aleatorio”.

Analizando este paso, suponemos que el numero obtenido de la función rand() es el 12 y lo dividimos entre el numero 6;  obteniendo su modulo (residuo) que es igual a 0 (imagen1).

imageimagen1

La variable “aleatorio” que es igual a “0”  se encuentra en el rango de 0 a 5 y podemos confirmar que todas las variables “aleatorioque sean obtenidas aplicado a la función rand() una operación “modulo de 6 [ rand() % 6 ] se encontraran en este rango (0 a 5).

Para confirmar este argumento; asignemos otro valor ficticio a nuestra función rand(), por ejemplo el numero 8:

imagen2 

El numero obtenido es el 2, por lo que una vez mas nuestra variable “aleatorio” se encuentra en el rango de 0 a 5. Así podemos continuar asignando valores ficticios y arbitrarios a la función rand() y demostraremos que la variable “aleatorio” puede obtener el valor 0 ó 1 ó 2 ó 3 ó 4 ó 5  sea cual sea el dividendo con el que alimentemos la división.

El residuo de 12 entre 6 es cero “0” , lo comprobamos con el siguiente programa:

   1: #include <iostream.h>

   2: #include <stdlib.h>

   3: #include <conio.h>

   4:  

   5: int main(){

   6: int residuo=0;

   7: /*

   8: inicializar la variable var_rand en 12 es como

   9: simular que el resultado de la funcion

  10: rand fue igual a 12

  11: */

  12: int var_rand=12;

  13: //Digamos que equivale a

  14: //aleatorio= rand() % 6

  15: residuo= var_rand % 6;

  16: cout<<"El numero aleatorio generado es: "<<residuo <<endl;

  17: getch();

  18: }

La variable var_rand viene a emular el resultado de la función rand() solo que aquí nosotros damos el valor arbitrariamente (en este caso el 12).

🙂 muy bien , con eso espero allá quedado claro; ahora si quisiera un numero aleatorio entre el 0 y el 20 , solo cambiaria la línea del programa:

aleatorio = rand() % 21;

y si lo quiero en  un rango 0 a 50 entonces:

aleatorio = rand() % 51;

… y de rango 0 a 87:

aleatorio = rand() % 88;

Como ya nos dimos cuenta la formula es sencilla [ aleatorio = rand() % (N+1); ], si queremos hacer un rango de 0 a n , entonces la línea de código quedaría así:

aleatorio = rand() % n+1;

 
Pero aun con el rango continuamos con el problema que cada vez que ejecutamos el programa se generan los mismos números.

Función srand()

Para solucionar ese problema contamos con la función srand() con la cual indicamos el numero semilla con el que empezara el algoritmo para generar números aleatorios.

#include <iostream.h>

#include <stdlib.h>

#include <time.h>

#include <conio.h>

 

int main()

{

 long int aleatorio=0;

 srand(1);

 aleatorio = rand()%11;

 cout<<"Numero aleatorio de 0 a 10"<<endl;

 cout<<aleatorio;

getch();

}

Ya podemos generar realmente números aleatorios el único problema es que tenemos que cambiar el numero semilla manualmente (ósea borramos en el código el numero 1 de la función srand(1) y escribimos otro srand(34) )  efectivamente salen números aleatorios … pero si queremos GENERAR VARIOS NUMEROS ALEATORIOS EN UNA MISMA EJECUCION DEL PROGRAMA:

   1: #include <iostream.h>

   2: #include <stdlib.h>

   3: #include <time.h>

   4: #include <conio.h>

   5:  

   6: int main()

   7: {

   8:  long int aleatorio=0;

   9:  cout<<"Programa que genera 10 numeros aleatorios con srand(1)"<<endl;

  10:  srand(1);//Utilizo el numero 1 como semilla

  11:  for(int i=1; i<=10; i++){ // Ciclo for para generar 10 numeros

  12:  aleatorio = rand()%11;

  13:  cout<<i<<".-Aleatorio = "<<aleatorio<<endl;

  14:  }

  15: getch();

  16: }

🙂 Wow!! funciona… …. aunque tiene un detallito… si lo ejecutamos de nuevo SALDRAN LOS MISMOS NUMEROS y no queremos eso… lo que queremos es que cada vez que se ejecute el programa genere números aleatorios nuevos. Para solucionarlo utilizaremos un truquito el cual es inicializar nuestra semilla con la hora del sistema rand(hora_del_sistema) 😀 .

1.- Agregamos la librería time.h

2.- Modifico la línea srand(1) a srand (time(NULL))

   1: #include <iostream.h>

   2: #include <stdlib.h>

   3: #include <time.h>

   4: #include <conio.h>

   5:  

   6: int main()

   7: {

   8:  long int aleatorio=0;

   9:  cout<<"Programa que genera 10 numeros aleatorios con srand
(time(NULL))"
<<endl;

  10:  srand (time(NULL)); //Utilizo la hr del sistema como semilla

  11:  for(int i=1; i<=10; i++){ // Ciclo for para generar 10 numeros

  12:  aleatorio = rand()%11;

  13:  cout<<i<<".-Aleatorio = "<<aleatorio<<endl;

  14:  }

  15: getch();

  16: }

*DATO: la función srand() solamente la podemos usar una vez en el programa no traten de engañar al programa usándola varias veces por que los tirara de a locos

bueno.. esta es una forma BASICA de generar números aleatorios, existen otras cuantas como por ejemplo usar la función  getpid(); (regresa el ID del programa en ejecución asignado por el Sistema Operativo)  envés de usar time(NULL); y otras miles de formas mas.

Si desean pueden descargar el código de estos ejemplos:

page_white_compressed1[1] Descargar ejemplos de números aleatorios en C y C++

-Los ejemplos fueron compilados con Borland C++ 5.2

 

El dato extra:

Existen otras dos funciones para generar numero aleatorios las cuales son: drand48() y srand48() si desean saber mas de ellas visiten este link

Puedo recomendar un libro que se llama: El arte de la intrusión de autor Kevin Mitnick y editorial ALFAOMEGA.RA-MA donde en su primer capitulo se aprecia la importancia de generar números aleatorios que realmente sean aleatorios 😀 que mejor ejemplo que un CASINO ELECTRONICO ¿no?.

Update:

He mejorado la explicación del por que utilizamos el modulo para delimitar a un rango la generación de números aleatorios.

Si desean hacer un programa que genere números aleatorios con un rango definido ( numero mínimo a obtener y numero máximo a obtener) pueden revisar el siguiente programa: page_white_compressed1[1] DESCARGAR

[+][+][+]

Fuentes:

http://www.chuidiang.com/clinux/funciones/rand.php

http://www.agner.org/random/

http://www.daniweb.com/forums/thread1769.html

Complemento para Windows Live Writer

Anuncios

Nube de etiquetas