2010-06-18 22 views
11

bien la búsqueda de tutoriales en la generación de números aleatorios en el IC hallado this topicLa generación de números aleatorios en C

Cuando intento utilizar la función rand() sin parámetros, siempre me 0. Cuando trato de utilizar la función con los parámetros rand() , Siempre obtengo el valor 41. Y cada vez que intento usar las funciones arc4random() y random(), aparece un error LNK2019.

Esto es lo que he hecho:

#include <stdlib.h> 
int main() 
{ 
    int x; 
    x = rand(6); 
    printf("%d", x); 
} 

Este código genera siempre 41. ¿Dónde estoy haciendo mal? Estoy ejecutando Windows XP SP3 y utilizando el símbolo del sistema VS2010 como compilador.

+0

try 'rand() * 10' – deostroll

Respuesta

30

Debe llamar a srand() antes de llamar a rand para inicializar el generador de números aleatorios.

o bien llamarlo con una semilla específica, y siempre obtendrá la misma secuencia pseudo-aleatoria

#include <stdlib.h> 

int main() 
{ 
    srand (123); 
    int random_number = rand(); 
    return 0; 
} 

o llamarlo con un cambio de las fuentes, es decir, la función de tiempo

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

int main() 
{ 
    srand (time(NULL)); 
    int random_number = rand(); 
    return 0; 
} 

En respuesta al comentario de Moon rand() genera un número aleatorio con una probabilidad igual entre 0 y RAND_MAX (una macro predefinida en stdlib.h)

Puede asignar este valor a un rango menor, p. Ej.

int random_value = rand(); //between 0 and RAND_MAX 

//you can mod the result 
int N = 33; 
int rand_capped = random_value % N; //between 0 and 32 
int S = 50; 
int rand_range = rand_capped + S; //between 50 and 82 

//you can convert it to a float 
float unit_random = random_value/(float) RAND_MAX; //between 0 and 1 (floating point) 

Esto podría ser suficiente para la mayoría de usos, pero vale la pena señalar que en el primer caso se utiliza el operador mod introduce un ligero sesgo si N no se divide uniformemente en RAND_MAX + 1.

Los generadores de números aleatorios son interesantes y complejos, se dice que el generador rand() en la biblioteca estándar C no es un generador de números aleatorios de gran calidad, lea (http://en.wikipedia.org/wiki/Random_number_generation para una definición de calidad).

http://en.wikipedia.org/wiki/Mersenne_twister (fuente http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html) es una alta calidad generador de números aleatorios popular.

Además, no tengo conocimiento de arc4rand() o al azar() por lo que no puedo hacer ningún comentario.

+1

Gracias. Pero aún así, quedan dos preguntas. 1) ¿Qué hacer si quiero generar números aleatorios en un rango específico, digamos de 0 a 9? He intentado 'rand (10)' pero no ayudó. 2) ¿Cuál fue el problema conmigo usando 'arc4rand()' y 'random()'? – MoonStruckHorrors

+0

Excelente. Nuevamente, gracias. – MoonStruckHorrors

5

Necesita sembrar su PRNG para que comience con un valor diferente cada vez.

Un simple pero baja calidad de las semillas es utilizar la hora actual:

srand(time(0)); 

Esto le ayudará a empezar pero se considera baja calidad (es decir, por ejemplo, no utilizan que si están tratando de generar claves RSA).

Fondo. Los generadores de números pseudoaleatorios no crean secuencias de números aleatorios verdaderos, sino que simplemente los simulan. Dado un número de punto de partida, un PRNG siempre devolverá la misma secuencia de números. Por defecto, comienzan con el mismo estado interno, por lo que devolverán la misma secuencia.

Para no obtener la misma secuencia, cambia el estado interno. El acto de cambiar el estado interno se denomina "siembra".

1

primero tiene que semilla del generador, ya que no genera números aleatorios reales!

Prueba esto:

#include <stdlib.h> 
#include <time.h> 
int main() 
{ 
    // random seed, time! 
    srand(time(NULL)); // hackish but gets the job done. 
    int x; 
    x = rand(); // everytime it is different because the seed is different. 
    printf("%d", x); 
} 
+0

Puede que no sea diferente ** cada vez ** ejecuta el código (intente ejecutar su código en un bucle bash 'while true; do ./prog; done'). La entrada del blog de Raymond Chen hoy se trata de este tema exacto (http://blogs.msdn.com/b/oldnewthing/archive/2010/06/17/10026183.aspx) –

+0

Gracias. Una buena lectura de hecho. – AraK

3
#include <stdlib.h> 

int main() 
{ 
    int x; 
    x = rand(6); 
    printf("%d", x); 
} 

Especialmente como un principiante, usted debe preguntar a su compilador para imprimir todas las advertencias sobre el mal código que puede generar. Los compiladores modernos conocen muchas advertencias diferentes que te ayudan a programar mejor. Por ejemplo, cuando se compila este programa con el compilador de C de GNU:

$ gcc -W -Wall rand.c 
rand.c: In function `main': 
rand.c:5: error: too many arguments to function `rand' 
rand.c:6: warning: implicit declaration of function `printf' 

que se produzcan dos advertencias aquí. El primero dice que la función rand solo toma cero argumentos, no uno como lo intentó. Para obtener un número aleatorio entre 0 y n, puede usar la expresión rand() % n, que no es perfecta, pero está bien para n. Los números aleatorios resultantes normalmente no están distribuidos uniformemente; los valores más pequeños se devuelven con más frecuencia.

La segunda advertencia indica que está llamando a una función que el compilador desconoce en ese momento. Debe decirle al compilador diciendo #include <stdio.h>. Qué archivos de inclusión son necesarios para qué funciones no siempre es simple, pero preguntar la especificación de Open Group para sistemas operativos portátiles funciona en muchos casos: http://www.google.com/search?q=opengroup+rand.

Estas dos advertencias le dicen mucho sobre la historia del lenguaje de programación C. Hace 40 años, la definición de una función no incluía la cantidad de parámetros o los tipos de los parámetros. También estuvo bien llamar a una función desconocida, que en la mayoría de los casos funcionó. Si desea escribir código hoy, no debe confiar en estas características anteriores, sino que debe habilitar las advertencias de su compilador, comprender las advertencias y luego corregirlas adecuadamente.

3

También, PRNGs de congruencia lineal tienden a producir más aleatoriedad en los bits más altos que en los bits más bajos, por lo que a Cap el resultado no utilice módulo, pero en lugar de utilizar algo como:

j = 1 + (int) (10.0 * (rand()/(RAND_MAX + 1.0))); 

(Este uno es de "Numerical Recipes en C", CH.7)

1

O bien, para conseguir un int pseudo-aleatorio en el rango de 0 a 19, por ejemplo, se puede utilizar los bits más altos de esta manera:

j = ((rand() >> 15) % 20; 
+1

¿Por qué el '>> 15'? En algunas implementaciones 'RAND_MAX' es solo' 0x7fff', por lo que el cambio de un valor aleatorio por esa cantidad siempre sería '0'. –

1
int *generate_randomnumbers(int start, int end){ 
    int *res = malloc(sizeof(int)*(end-start)); 
    srand(time(NULL)); 
    for (int i= 0; i < (end -start)+1; i++){ 
     int r = rand()%end + start; 
     int dup = 0; 
     for (int j = 0; j < (end -start)+1; j++){ 
      if (res[j] == r){ 
       i--; 
       dup = 1; 
       break; 
      } 
     } 
     if (!dup) 
      res[i] = r; 
    } 
    return res; 
} 
Cuestiones relacionadas