2009-10-31 15 views
47

Esto es realmente extraño, y no puedo ver por qué sucede esto. En el ciclo foreach, estoy iterando a través de una colección de clase A, y para cada clase, llamo al método Count(), donde se generan los números r1 y r2 del rango [-1,1]. El problema es que Random.Next devuelve los mismos números "aleatorios" para cada instancia. Cuando los resultados para la primera instancia son 0 y -1, los mismos serán devueltos de las siguientes instancias. Por favor, ¿podría decirme por qué está pasando esto? Además, no puedo obtener resultados diferentes en cada instancia de clase A. Este es el código:Random.Next devuelve siempre los mismos valores

class a 
{ 
Random rnd = new Random(); 
private void Count() 
{ 
    int r1 = rnd.Next(-1, 1); 
    int r2 = rnd.Next(-1, 1); 
} 
} 
class b 
{ 
List<a> listofA=new list<a>(); 
foreach (a ACLASS in listofA) 
{ 
    ACLASS.Count(); 
} 
} 

Respuesta

94

El problema es que va a crear instancias de la clase Random demasiado cerca en el tiempo.

Cuando crea un objeto Random, se siembra con un valor del reloj del sistema. Si crea instancias Random demasiado cercanas en el tiempo, todas serán sembradas con la misma secuencia aleatoria.

Crea un solo objeto Random y pasa su referencia al constructor cuando creas instancias de la clase "a", en lugar de crear un objeto Random para cada instancia "a".

+1

me olvidó, así, que solía tener el mismo problema en su día haciendo Bingo Cartones de un club, y en ese entonces, utilicé el peor truco jamás conocido por el hombre: pausar el hilo por 2 personas inexperta y loca ... Lo suficientemente loca, tengo una clase que crea nombres aleatorios con una declaración aleatoria estática en la parte superior de todo. –

5

Incluye una instancia aleatoria para cada instancia A. Parece que todos obtienen el mismo valor de inicialización predeterminado. Probablemente desee hacer un muestreo aleatorio estático para todas las instancias A y usarlo repetidamente, o alternativamente proporcionar un valor inicial a la instancia Random() en el constructor A.

8

Está creando una nueva instancia de Random muy cerca una de la otra (su ciclo es muy ajustado) por lo que cada instancia está utilizando efectivamente el mismo valor inicial.

Un mejor enfoque sería crear una instancia y pasarla a su método Count.

Usted problably saben siguiente bit, pero yo lo incluiremos aquí para completar:

El MSDN tiene los detalles sobre esto, pero básicamente su problema es el método que está utilizando Random.Next genera:

Un entero de 32 bits con signo mayor o igual que minValue y menor que maxValue; es decir, el rango de valores de retorno incluye minValue pero no maxValue. Si minValue es igual a maxValue, se devuelve minValue.

debido a esto sus llamadas volverán -1 o 0.

7

Usar un único generador de números aleatorios, estática para todas las instancias de la clase.

class a 
{ 
    private static Random rnd; 
    static a() { 
     rnd = new Random(); 
    } 
    private void Count() 
    { 
    int r1 = rnd.Next(-1, 2); 
    int r2 = rnd.Next(-1, 2); 
    } 
} 

nota el cambio para darle números en el rango -1,1 -1,0 en lugar de

+0

Creo que con este rango también puede devolver 1 y solo quieren 0 y -1? – Lucas

+0

@Svante editó la pregunta para hacer que el intervalo se abriera para coincidir con el ejemplo del código.La pregunta original especificaba un intervalo cerrado, aunque no utilizaba un lenguaje preciso. Creo que el código era incorrecto y voy a restaurar la pregunta para especificar un intervalo cerrado. – tvanfosson

+0

@tvanfosson ¿Me puede decir por qué funciona? No entiendo cómo hacer esta estática te da aleatoriedad. Sé que funciona, pero no por qué. Todavía están muy cerca en el tiempo. Gracias. – johnny

Cuestiones relacionadas