2012-02-09 6 views
5

Sto avendo problemi con la generazione di numeri casuali in C#. Se I RUN questa applicazione modulo direttamente, la generazione del numero casuale è uguale per tutti.generazione di numeri casuali: restituendo lo stesso numero in C# se corro. ok se Debug passo dopo passo

Se i DEBUG questa riga per riga premendo F10, quindi genererà diversi numeri casuali. Perché questo sta accadendo? Cosa devo fare per generare numeri casuali diversi?

Greyhound.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace ADayAtTheRaces 
{ 
    class Greyhound 
    { 
     int location=0; 
     Random randomize = new Random(); 

     public int run() 
     { 
      location = randomize.Next(0, 100); 
      return location; 
     } 
    } 
} 

Form1.cs

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace ADayAtTheRaces 
{ 
    public partial class Form1 : Form 
    { 
     Greyhound[] greyHound = new Greyhound[4]; 
     ProgressBar[] progressBar = new ProgressBar[4]; 
     public Form1() 
     { 
      InitializeComponent(); 
      for (int i = 0; i < 4; i++) 
      { 
       greyHound[i] = new Greyhound(); 
      } 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      for (int i = 0; i <= 3; i++) 
      { 
       progressBar[i].Value = greyHound[i].run(); 
      } 
     } 
    } 
} 

risposta

10

Non istanziare un nuovo oggetto Random ogni volta, invece usarlo come un membro static:

class Greyhound 
{ 
    static Random randomize = new Random(); 
    int location=0; 

    public int run() 
    { 
     location = randomize.Next(0, 100); 
     return location; 
    } 
} 

Vedi Random.Next returns always the same values

+0

sì. grazie. Il mio problema è stato risolto quando l'ho dichiarato statico. – SHRI

3

si sta creando una quantità X di nuovo a caso, allo stesso tempo.

Quello che dovresti fare è creare una nuova istanza di Random e quindi all'interno di foreach (o qualsiasi loop) usare instance.Next().

Questo dovrebbe darvi i valori unici.

Speranza che aiuta

2

la vostra risposta è qui: Random Constructor

La distribuzione dei numeri generati è uniforme; ogni numero è ugualmente probabile che venga restituito.

Il valore di inizializzazione predefinito è derivato dall'orologio di sistema ed ha una risoluzione finita . Di conseguenza, diversi oggetti casuali creati nella successione di chiusura da una chiamata al costruttore predefinito avranno valori di seme predefiniti identici e, pertanto, genereranno serie identiche di numeri casuali . Questo problema può essere evitato utilizzando un singolo oggetto casuale per generare tutti i numeri casuali. È inoltre possibile aggirare lo modificando il valore di inizializzazione restituito dall'orologio di sistema e quindi fornendo in modo esplicito questo nuovo valore di inizializzazione al costruttore Random (Int32) . Per ulteriori informazioni, consultare il costruttore Random (Int32).

si crea tutti quegli oggetti Random sostanzialmente allo stesso tempo nel ciclo e tutti vengono inizializzati con il seme dipendente stesso tempo, cercare di creare un solo oggetto statico o specificare il seme in modo diverso. nel debug il tempo di attesa del tuo spostamento riga per riga rende già il seme diverso.

+0

Questa dovrebbe essere la risposta selezionata. – Galilyou

1

Davide ha perfettamente ragione. In termini pratici, questo è il modo in cui correggi il tuo codice.

In Form1, creare una nuova istanza di Random:

Random rng = new Random(); 

e passarlo nella chiamata a Greyhound.run() come questo:

for (int i = 0; i <= 3; i++) 
{ 
    progressBar[i].Value = greyHound[i].run(rng); 
} 

poi dentro Greyhound.cs, rimuovere la riga

Random randomize = new Random(); 

e cambiare

public int run() 

a

public int run(Random randomize) 

Questo renderà le diverse istanze della vostra classe Levriero riutilizzare la stessa istanza di Random, risolvendo così il problema .

1

provare a fare randomize statica. Immagino che il problema derivi dal fatto che il seme dipende dal tempo.

1

Il motivo per cui si ottiene lo stesso numero casuale per tutti è che si sta creando un oggetto casuale per ogni istanza. Il generatore casuale viene seminato dall'orologio, quindi quando crei oggetti casuali troppo vicini nel tempo, finiranno tutti con lo stesso seme e genereranno gli stessi numeri casuali.

Quando si esegue il debug del codice, gli oggetti vengono creati con un lungo intervallo di tempo, quindi i generatori casuali vengono generati da diversi valori di clock.

Utilizzare un singolo generatore casuale, e passare che nel costruttore degli oggetti:

namespace ANightAtTheOpera { 

    class Greyhound { 
    int location=0; 
    Random randomize; 

    public Greyhound(Random rnd); 
     randomize = rnd; 
    } 

    public int run() { 
     location = randomize.Next(0, 100); 
     return location; 
    } 
    } 

} 

inizializzazione:

Random rnd = new Random(); 
for (int i = 0; i < 4; i++) { 
    greyHound[i] = new Greyhound(rnd); 
} 
1

Ogni stai istanziare un'istanza di Greyhound si istanziare System.Random . Il costruttore predefinito per System.Random utilizza System.Environment.TickCount come seme per la generazione del numero casuale. System.Environment.TickCount ha una risoluzione di un millisecondo e tu stai creando istanze molto più velocemente di così. Forse rendi l'istanza System.Random che stai usando static ... che risolverà il problema.

Problemi correlati