Home :: Lenguaje :: Algoritmos :: Cómo generar números aleatorios en C++
 
Como-generar-numeros-aleatorios-en-C++

Cómo generar números aleatorios en C++

dic 07, 2009 en Algoritmos por Victor Parasi

Uno, dos, tres, cuál es el número que obtendré esta vez?. No sé si te ha pasado pero cuando deseo generar un número aleatorio, a veces, se convierte en un gran dolor de cabeza. No por lo difícil que puede resultar el comando o rutina a utilizar, sino porque siempre sale el mismo número, una y otra vez. Espero que al leer este artículo te pueda ayudar a resolver este problema.

FacebookGoogle BookmarksGoogle GmailTwitterYahoo MailHotmailLinkedInShare

Te ha ocurrido, aunque sea una vez que, al momento de generar un número aleatorio en C++, siempre te sale el mismo número?. Bueno, a mi también. Lo que te escribiré ahora son los métodos que utilizo para evitar esto.

Antes de empezar, debes de estar tan convencido como yo, que la función que debemos utilizar para generar un número aleatorio es: rand(), y si no lo estas, pues convéncete porque esta función viene desde ANSI C y es la que más se usa.

La función rand() genera un número aleatorio entre 0 y RAND_MAX-1. Donde RAND_MAX es una constante entera cuyo valor es de 32767, aunque a veces su valor cambia debido básicamente al compilador que se está usando.

RAND_MAX y rand() vienen definidas en la librería stdlib.h

Ejemplo de como usar la función rand()

#include <stdio.h>
#include <stdlib.h>
int main()
{
	printf("%d", rand());
	return 0;
}

En el código anterior, puedes apreciar que en la línea 5 se invoca a la función rand(), y el número aleatorio generado es impreso en pantalla, mediante la función printf.

Ahora, si ejecutas esta aplicación reiteradamente, siempre te dará el mismo número aleatorio, por qué?. La respuesta es matemática más que computacional. Todo número aleatorio se obtienen a partir de un número llamado semilla, por lo que si la semilla es la misma, siempre, obtendremos el mismo número aleatorio.

Cambiando la semilla

Para cambiar la semilla, con la cual se genera un número aleatorio, debemos de utilizar la función srand(), definida igualmente en stdlib.h

Ahora, aquí está el truco. La semilla debe de ser inicializada, utilizando un valor que no se repita, de tal forma que puedas disminuir la probabilidad de que salga el mismo número siempre. La forma más sencilla de hacer eso es utilizar la fecha y hora de la computadora como semilla para generar el número.

Para poder obtener la fecha y hora de la computadora, utilizaremos la función time() definida en time.h

Ejemplo de como usar rand(), srand() y time()

#include <stdio.h>
#include <time.h>
int main()
{
	srand((unsigned)time(NULL));
	printf("%d\n", rand());
	return 0;
}

Y si deseas crear más de un número al azar, el código es el siguiente:

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

int main()
{
	srand((unsigned)time(NULL));
	for (int i=0; i<10; i++)
		printf("%d\n",rand());
	return 0;
}

Mira con atención la línea número 9, la estructura repetitiva FOR, permite repetir (en este caso 10 veces), la creación de un número al azar y debe ir después de inicializar la semilla. En general, no recomiendo invocar a la función srand() dentro de cualquier estructura repetitiva. SIEMPRE SE DEBE DE INICIALIZAR LAS SEMILLAS, UNA SOLA VEZ AL INICIO DE LA APLICACION y por qué? la respuesta se puede deducir fácilmente, si invocamos a a la función srand() reiteradamente, estaremos reiniciando el valor de la semilla, con lo que se repetirá todo.

Crear número aleatorio dentro de un intervalo

Con lo visto anteriormente, podemos crear un número aleatorio entre 0 y la constante RAND_MAX, supongo que te estarás preguntando, y si tengo que generar un número dentro de un intervalo determinado, como hago?

Primer método : Uso del operador %

Si lo que deseas es generar, por ejemplo un número aleatorio entre 0 y N-1, te recomiendo obtener el resultado del residuo de una división entera (%) entre el valor obtenido por la función rand() y el valor de N.

Complicado?, no lo creo, mira el ejemplo:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
	srand((unsigned)time(NULL));

	for (int i=0; i<10; i++)
		printf("%d\n",rand()%10);

	return 0;
}

Puedes apreciar, claramente, que en la línea 9, lo que se hace es un residuo de la división entera entre rand() y 10. Esto genera un valor aleatorio entre 0 y 9.

Ahora si tu quieres un valor entre 0 y 50, que debes de hacer?.. Claro! sólo cambiar el número 10 por 51. Y si quieres un valor entre 0 y 7?.. Si!, reemplaza el 10, del código, por un 8, y listo! Funciona!

Segundo método : Definiendo los límites del intervalo

La segunda forma es cuando defines los límites inferior (A) y superior (B) de un intervalo y sólo quieres obtener un número aleatorio comprendido en ese rango de números.

Hacer esto, es sencillo y lo explico por partes:

Primero, recuerda que al hacer rand()%N, obtienes un valor entre 0 y N-1.

Segundo, al ejecutar rand()%N, el mínimo valor obtenido es 0, por lo que si le sumas el límite inferior (A) del intervalo definido, A será el mínimo valor obtenido. Ejemplo: A+rand()%N

Tercero, si tu quieres obtener como máximo valor aleatorio el límite superior (B) del intervalo , debes de reemplazar N. Pero no reemplazarlo por B, sino por (B-A)+1. Por qué le sumo uno?, porque sino lo hago, el máximo valor aleatorio generado será B-1.

De esta forma te quedaría el siguiente código:

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

int main()
{
	srand((unsigned)time(NULL));
	int A = 30;
	int B = 100;
	printf("%d\n", A + rand() % ((B-A)+1));
	return 0;
}

En el código anterior, se está generando un valor aleatorio entre 30 y 100.

Crear número aleatorio con decimales

En Unix y linux, existe dos funciones definidas en la libreria stdlib.h, que nos permiten generar un número aleatorio con decimales. Estas dos funciones son srand48() y drand48(). En el caso de Windows, no existe función similar, salvo que tu mismo lo codifiques.

Una forma sencilla de obtener un número aleatorio con decimales, pero no la mejor, es la siguiente:

#include <stdio.h>
#include <time.h>
int main()
{
	srand((unsigned)time(NULL));
	printf("%lf\n", (double)rand() / (double)RAND_MAX);
	return 0;
}

Mira con atención la línea 6, se hace una división, donde ambos operadores son del tipo double.

Si, si ya se que esta solución es bien sencilla, pero a la vez, práctica. Lo que a continuación mostraré es una función que genera una número decimal, entre 0 y 1. El código original de la función es de Steve Summit, pero yo he realizado unas pequeñas modificaciones para que trabaje mejor.

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

#define MAX 2.0e21

double drand48(void)
{
	double valor = 0.0;
	double d = RAND_MAX * 1.0;
	double i;
	for(i = MAX; i > rand(); i /= (RAND_MAX + 1))
	{
		valor += rand()/d;
		d *= RAND_MAX + 1 ;
	}
	return valor;
}
//----------------------------------
int main()
{
	double x;
	srand((unsigned)time(NULL));
	x = drand48();
	printf("%lf", x);
	return 0;
}

Autor: Victor Parasi

Siempre es difícil escribir sobre uno mismo, qué contar, o por donde empezar, suele ser todo un dilema al momento de presentarse. Aquí vamos. Les diré que soy peruano, Ingeniero por vocación, dedicado a la docencia y siempre en la búsqueda de programar cada vez mejor. Aunque a veces algo terco, sé que no todo en la vida es blanco o negro. Existe el Open Source, y lo respeto pero me llevo mejor con el .Net. Si me hablas de preferencias, te digo que C#, C++, una buena película, colores oscuros, escribir, leer e investigar. Para terminar les diré que amo muchísimo a una mujer espectacular y que es la dueña de mi corazón.


Comentarios (3)

luis dice:

chido lo estaba buscando gracias aunque cuando lo muestra en la pantalla no dura ni un segundo como le hago para que se queden ahi

Hola, lo que necesitas es generar una pausa, por lo que añade la siguiente instrucción:
getch().
La debes incluir justo antes del return 0.

miguel dice:

genial viejo exelente!!

Deja un comentario

   

copstone en Facebook

Otros artículos

C Sharp es un lenguaje orientado a objetos, por lo que era una tarea pendiente indicar como se define un clase, te dejo este post para que aprendas lo sencillo que es.

FacebookGoogle BookmarksGoogle GmailTwitterYahoo MailHotmailLinkedInShare

Alguna vez te haz preguntado cómo hace una función como por ejemplo el printf para recibir una cantidad de parámetros indefinida? En este artículo te voy a enseñar a escribir funciones que no necesiten una cantidad definida de parámetros.

FacebookGoogle BookmarksGoogle GmailTwitterYahoo MailHotmailLinkedInShare

Este es un artículo que todo programador de Windows debería leer. Si quieres poder tener un mayor control sobre lo que pasa en Windows y poder manipular sus ventanas como mejor te parezca, es necesario que conozcas primero el funcionamiento de las ventanas de Windows.

FacebookGoogle BookmarksGoogle GmailTwitterYahoo MailHotmailLinkedInShare

Amplia tus conocimientos de programación web y aprende un poco acerca de cookies y como puedes utilizarlas con php y javascript para mejorar tus aplicaciones web.

FacebookGoogle BookmarksGoogle GmailTwitterYahoo MailHotmailLinkedInShare

Cuando hablamos de Estructura de Datos, se nos viene a la mente el concepto de Arreglos, Listas, etc. En el post anterior hablamos sobre las Pilas, es hora de saber que son las Colas cuando estamos trabajando con Estructura de Datos.

FacebookGoogle BookmarksGoogle GmailTwitterYahoo MailHotmailLinkedInShare

Calendario

diciembre 2009
L M X J V S D
« nov   ene »
 123456
78910111213
14151617181920
21222324252627
28293031  

Categorías

Comparte este artículo

  • Facebook
  • Google Bookmarks
  • Google Gmail
  • Twitter
  • Yahoo Mail
  • Hotmail
  • LinkedIn
  • Share
TIENES ALGO QUE PREGUNTAR? ESCRÍBENOS AQUÍ

Copyright © 2012 - Programando por diversion

Subir