92 votos

Cómo semilla una clase al azar para evitar valores duplicados al azar

tengo el siguiente código dentro de un método estático en una clase estática

Random r = new Random();
int randomNumber = r.Next(1,100);

¿tengo esto dentro de un bucle y sigo recibiendo el mismo randomNumber?

¿cualquier sugerencia aquí?

243voto

joppiesaus Puntos 690

Es una generación buena semilla para mí:

Random rand = new Random(Guid.NewGuid().GetHashCode());

Es muy aleatorio. La semilla es siempre diferente porque la semilla es también aleatorizada generado.

88voto

Mehrdad Afshari Puntos 204872

Usted no debe crear un nuevo Random ejemplo de un bucle. Intente algo como:

var rnd = new Random();
for(int i = 0; i < 100; ++i) 
   Console.WriteLine(rnd.Next(1, 100));

La secuencia de números aleatorios generados por un solo Random ejemplo se supone que para ser distribuidos de manera uniforme. Mediante la creación de un nuevo Random de instancia para cada número aleatorio en sucesiones rápidas, es probable que la semilla de ellas con idénticos valores y generan idénticos números aleatorios. Por supuesto, en este caso, la consecuencia generada estará lejos de una distribución uniforme.

En aras de la exhaustividad, si usted realmente necesita para reinicializar un Random, vamos a crear una nueva instancia de Random con la nueva semilla:

rnd = new Random(newSeed);

55voto

Jon Skeet Puntos 692016

Generalmente, la mejor idea es tener una sola instancia de Random por hilo - usted no desea crear una instancia regularmente como usted va a terminar con repeticiones como hemos visto, y usted no quiere a la reutilización de casos entre los subprocesos Random no es thread-safe.

He aquí un poco de clase a ayudar con eso:

using System;
using System.Threading;

public static class RandomHelper
{
    private static int seedCounter = new Random().Next();

    [ThreadStatic]
    private static Random rng;

    public static Random Instance
    {
        get
        {
            if (rng == null)
            {
                int seed = Interlocked.Increment(ref seedCounter);
                rng = new Random(seed);
            }
            return rng;
        }
    }
}

Usted puede entonces utilizar de forma segura RandomHelper.Instance desde cualquier hilo. Idealmente, para la capacidad de prueba, usted debe tratar de usar esta relativamente rara - el tratamiento de la aleatoriedad como una dependencia, y pasar a la Random de referencia en los métodos que necesitan.

Tenga en cuenta que:

  • El rng campo tiene el [ThreadStatic] atributo aplicado, por lo que es efectivamente una variable distinta para cada subproceso.
  • Inicializamos seedCounter (una vez) basado en la hora actual, pero luego se incremento en un hilo de forma segura cada vez que necesitamos una nueva instancia para otro hilo.

14voto

PPC Puntos 578

En caso de que no puede por alguna razón usas el mismo Random una y otra vez, tratar de inicializar con algo que cambia todo el tiempo, como el tiempo mismo.

new Random(new System.DateTime().Millisecond).Next();

Recuerde que aunque es mala práctica.

4voto

Omidoo Puntos 142

Este funciona para mí:

private int GetaRandom()
    {
        Thread.Sleep(1);
        return new Random(DateTime.Now.Millisecond).Next();
    }

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X