2009-10-31 25 views
47

Questo è davvero strano, e non riesco a capire perché questo sta accadendo. Nel ciclo foreach, sto iterando attraverso una raccolta di classe A, e per ogni classe, chiamo il metodo Count(), dove i numeri r1 e r2 vengono generati dall'intervallo [-1,1]. Il problema è che Random.Next restituisce gli stessi numeri "casuali" per ogni istanza. Quando i risultati per la prima istanza sono 0 e -1, gli stessi verranno restituiti dalle seguenti istanze. Per favore, potresti dirmi perché questo sta accadendo? Inoltre, non riesco a ottenere risultati diversi in ogni istanza di classe A. Questo è il codice:Random.Next restituisce sempre gli stessi valori

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(); 
} 
} 

risposta

94

Il problema è che si sta creando istanze della classe Random troppo vicino nel tempo.

Quando si crea un oggetto Random, viene seminato con un valore dall'orologio di sistema. Se crei istanze di Random troppo vicine nel tempo, verranno seminate tutte con la stessa sequenza casuale.

Creare un singolo oggetto Random e passare il suo riferimento al costruttore quando si creano istanze della classe "a", invece di creare un oggetto Random per ogni istanza "a".

+1

ho dimenticato come bene, ho usato per avere lo stesso problema di nuovo nel corso della giornata rendendo Bingo Cartoni per un club, e in quel momento, ho usato il peggior trucco mai conosciuto dall'uomo: mettere in pausa il thread per 2 Ms. Inesperto e pazzo ... Abbastanza pazzo, ho una classe che crea nomi casuali con una dichiarazione casuale Random in cima di tutto. –

5

Si include un'istanza casuale per ogni istanza A. Sembra che stiano tutti ottenendo lo stesso valore di seme predefinito. Probabilmente vorresti creare una statica casuale per tutte le istanze A e usarla ripetutamente, o in alternativa fornire un valore seme all'istanza Random() nel costruttore A.

8

Stai creando una nuova istanza di Random molto ravvicinata (il tuo ciclo è molto stretto), quindi ogni istanza utilizza effettivamente lo stesso valore di inizializzazione.

Un approccio migliore sarebbe quello di creare un'istanza e passarla al metodo Count.

È problably sanno bit successivo, ma sarò includono qui per completezza:

Il MSDN ha i dettagli su questo, ma fondamentalmente il problema è il metodo che si sta utilizzando Random.Next genera:

Un numero intero con segno a 32 bit maggiore o uguale a minValore e minore di maxValue; cioè, l'intervallo di valori di ritorno include minValue ma non maxValue. Se minValue è uguale a maxValue, viene restituito minValue.

a causa di questo le chiamate restituiranno -1 o 0.

7

Utilizzare un unico generatore di numeri casuali statica per tutte le istanze della classe.

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 il cambiamento per darvi numeri nell'intervallo -1,1 anziché -1,0

+0

penso che con questo intervallo possa anche restituire 1 e vogliono solo 0 e -1? – Lucas

+0

@Svante ha modificato la domanda per rendere l'intervallo aperto in modo che corrisponda al codice di esempio.La domanda originale specificava un intervallo chiuso, sebbene non usasse un linguaggio preciso. Penso che il codice non sia corretto e ripristinerò la domanda per specificare un intervallo chiuso. – tvanfosson

+0

@ tvanfosson Puoi dirmi perché funziona? Non capisco come creare questa statica ti dia casualità. So che funziona, ma non perché. Sono ancora molto vicini nel tempo. Grazie. – johnny

Problemi correlati