[C con Clase] rand () y srand () en c

Steven Davidson srd4121 en njit.edu
Mar Mayo 26 19:30:04 CEST 2009


Hola Diego,

Diego wrote:
> Hola a todos tengo una consulta sobre el rand(), no se como
> implementarlo, por ejemplo en intervalos:
> 
> -6 a 6
> 
> 1 a 6
> 
> -6 a 0
> 
> o bien un rand() con numeros especificos  como  2, 4, 8 ó  2,5,9,4,1
> 
> no se como hacer para que me tire alguno de esos numeros al azar, no
> entiendo el termino de la semilla en el srand(), haber si me pueden
> ayudar por favor :-(
> 

Bien. Cada vez que invoques la función 'rand()', ésta genera un número 
pseudo-aleatorio entre 0 y 'RAND_MAX', la cual es una constante 
#definida en <cstdlib>. Esta generación de números realmente sigue una 
fórmula la cual crea varios números enteros en una serie. Para comenzar 
una serie u otra, invocamos 'srand()' la cual "planta un valor semilla" 
el cual comienza la generación de números pseudo-aleatorios. Por lo 
tanto, sólo debes invocar 'srand()' una sola vez en tu programa. 
Aconsejo hacer esto nada más entrar en 'main()'. Para ofrecer algo más 
de aleatoriedad, sugiero tomar el valor que representa la fecha y hora 
cada vez que ejecutes tu programa. Esto lo puedes hacer invocando la 
función 'time()'. Por ejemplo,

#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
   srand(time(0));
   ...
}

Ahora invocaríamos 'rand()' varias veces para obtener números aleatorios.

Para limitar el intervalo establecido de los valores generados por 
'rand()', tendrás que realizar algunas operaciones aritméticas. Lo que 
nos interesa hacer es cambiar la escala y luego mudar la serie para 
empezar por un número u otro. Por ejemplo, de -6 á 6, significa que hay 
13 números. Por lo tanto, tenemos que reducir el valor generado por la 
proporción de 'RAND_MAX+1' y 13. Posteriormente, tenemos que restar 6 (o 
sumar -6) al valor calculado para que empiece desde -6. Esto sería,

valor_generado = -6 + (int)( rand()*(13/(RAND_MAX+1.0)) + 0.5 );

En general, la fórmula es:

valor_generado = valor_inicial +
                  (int)( rand()*(intervalo/(RAND_MAX+1.0)) + 0.5 );

Otros programadores usan otra fórmula sencilla pero que puede generar 
números menos aleatorios es usando el operador del módulo para conseguir 
el resto de una división. Usando tu primer ejemplo, esto sería,

valor_generado = -6 + rand() % 13;

En general, la fórmula es:

valor_generado = valor_inicial + rand() % intervalo;

Como he dicho, esta fórmula es sencilla y rápida, pero no necesariamente 
correcta, que depende del intervalo.


Para conseguir números no secuenciales, entonces tienes dos opciones. Si 
existe una lógica para tales secuencias, entonces impleméntala. Si no 
existe, entonces crea un array con todos los números que quieres y usa 
'rand()' para generar números enteros a modo de índice para seleccionar 
cada número guardado en el array. Por ejemplo,

int array[5] = { 2,5,9,4,1 };

valor_generado = array[ calcular_indice(5) ];

donde,

int calcular_indice( int n )
{
   return (int)( rand()*(n/(RAND_MAX+1.0)) + 0.5 );
}


Sugiero que consultes la referencia acerca de éstas y otras funciones 
estándares de <cstdlib> en nuestra página. Puedes ir directamente a: 
http://c.conclase.net/librerias/libreria.php?lib=stdlib


Espero que esto te aclare las dudas.

Steven





Más información sobre la lista de distribución Cconclase