none
Generar un número realmente aleatorio.

    Question

  • Hola.

    Bueno, necesito generar un número realmente aleatorio, a veces un double comprendido entre 0 y 1 y otras veces un integer comprendido entre 2 valores (éstos valores extremos dependen de la situación en la cual emplee el algoritmo.

    Conozco el siguiente método de generar números aleatorios:

    Random r = new Random();
    int aleatorio = r.Next(minimo,maximo);
    
    

    Pero la verdad es que no me da buenos resultados, ya que me repite muchísimas veces el mismo número. ¿Cómo puedo realizarlo? Saludos.

    PD: tengo entendido que la clase Random genera los números en función del tiempo de la máquina, tal vez tenga que ver que son sentencias que se ejecutan una muy cercana a la otra, por eso me repite muchas veces el mismo número.

    Saturday, April 02, 2011 8:37 PM

Answers

  • En esta sencilla prueba, la distribución no parece ser (a simple vista), tan mala.

    Random random = new Random();
    int [] freq = new int[20];
       
    for (int k = 0; k < 20; k++) freq[k] = 0;
    for (int k = 0; k < 100000; k++) freq[random.Next(0, 20)]++;
    for (int k = 0; k < 20; k++) Console.WriteLine(freq[k]);

    Cada valor entre 0 y 20 sale aproximadamente 5000 veces. 

    Incluso con un número de muestras más reducido (500) se comporta decentemente.

    Obviamente, la instancia de random es única.

    • Marked as answer by Josecanalla Saturday, April 02, 2011 9:28 PM
    Saturday, April 02, 2011 9:15 PM

All replies

  • En esta sencilla prueba, la distribución no parece ser (a simple vista), tan mala.

    Random random = new Random();
    int [] freq = new int[20];
       
    for (int k = 0; k < 20; k++) freq[k] = 0;
    for (int k = 0; k < 100000; k++) freq[random.Next(0, 20)]++;
    for (int k = 0; k < 20; k++) Console.WriteLine(freq[k]);

    Cada valor entre 0 y 20 sale aproximadamente 5000 veces. 

    Incluso con un número de muestras más reducido (500) se comporta decentemente.

    Obviamente, la instancia de random es única.

    • Marked as answer by Josecanalla Saturday, April 02, 2011 9:28 PM
    Saturday, April 02, 2011 9:15 PM
  • hola

    tengo entendido que la clase Random genera los números en función del tiempo de la máquina

    en realidad lo hace basado en una semilla, este asegurara que dado el mismo valor se genere la misma secuencia

    Random.Next ese incomprendido

    Nota, el articulo esta en vb.net pero plantea muy bien la situacion

    a donde apunto esto que comentas del tiempo de la maquina quzas lo has visto para generar una similla distinta

     

    a veces un double comprendido entre 0 y 1 y otras veces un integer comprendido entre 2 valores (éstos valores extremos dependen de la situación en la cual emplee el algoritm

    ahora bien si necesitas que si o si no se repota un valor podrias aplciar algo similar a lo planteado aqui

    http://social.msdn.microsoft.com/Forums/es-ES/vcses/thread/f0d25893-14f3-4ab0-b5cc-dd3358a9d7fc

    me refiero als egundo ejemplo, como veras se usa una lista auxiliar en donde se van guardando los random genrados y cada vez que se quiere uno nuevo se hace un loop para consultar si esta contenido en la lista, si lo esta se pide al Random uno nuevo, asi hast que devuelva uno que no se encuantere en dicha lista

    de esta forma aseguras que sea 100% no repetido el valor que obtienes

    en el ejmeplo se usaba para tomar una frase, pero en tu caso podrias usari directo el nuemro, la idea es que uses una lista de valores generados y por cada nuevo la guardes alli para despues puedas consultar si se encuentra

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Saturday, April 02, 2011 9:24 PM
  • Los numeros aleatorios generados por un ordenador en realidad son "pseudo-aleatorios": dependen de una semilla inicial. Si esa semilla es por ejemplo la hora de la maquina, y creas dos objetos Random a la misma hora, pues produciran los mismos numeros aleatorios, por eso se te repiten. En un programa solo deberias crear un objeto Random y siempre utilizar ese para generar los numeros.

    Otro problema de los generadores de numeros aleatorios es que generan una secuencia de numeros que se repite, es decir, que lo mismo cuando hayas generador un millon de numeros, el siguiente sera igual que el primero. Este periodo de repeticion depende de lo bueno que sea el algoritmo de generacion de numeros aleatorios.

    En .NET hay un generador de numeros que es un poco mas dificil de usar pero es mucho mejor que Random que es la clase RNGCryptoServiceProvider:

    http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx

    En la documentacion tienes un ejemplo de codigo y todo.


    Vicente Cartas Espinel - MVP XNA/DirectX

    Twitter - VicenteCartas

    Blog about C# and XNA Development

    Blog about Role Playing Games


    Saturday, April 02, 2011 10:46 PM