2011-11-04 16 views
5

Ho una funzione ricorsiva e all'interno della funzione viene selezionato un elemento casuale da una matrice, ma indipendentemente da ciò che faccio continuo a ricevere lo stesso seme.Funzione ricorsiva per seme casuale. Come lo faccio?

static Random rand = new Random(); 
public String spintaxParser(String s) 
    { 
     if (s.Contains('{')) 
     { 
      int closingBracePosition = s.IndexOf('}'); 
      int openingBracePosition = closingBracePosition; 

      while (!s[openingBracePosition].Equals('{')) 
       openingBracePosition--; 

      String spintaxBlock = s.Substring(openingBracePosition, closingBracePosition - openingBracePosition + 1); 

      String[] items = spintaxBlock.Substring(1, spintaxBlock.Length - 2).Split('|'); 


      s = s.Replace(spintaxBlock, items[rand.Next(items.Length)]); 

      return spintaxParser(s); 
     } 
     else 
     { 
      return s; 
     } 
    } 

Qual è il modo migliore per gestire Random in una funzione ricorsiva?

+2

Avete qualche codice? –

+0

Hai provato a cercare una risposta a questo? Ci sono così tante domande sull'argomento dell'uso di Random - ad esempio, http://stackoverflow.com/questions/4855756/random-number-generation-same-number-returned (che a sua volta si riferisce ad altre domande correlate). – AAT

+0

Avremo bisogno di qualche codice sorgente per essere davvero in grado di aiutare. –

risposta

3

Dichiarare una singola istanza (statica) dell'oggetto Random al di fuori dell'ambito della funzione ricorsiva, quindi richiamare l'istanza dall'interno della funzione ricorsiva.

Il costruttore predefinito di Random lo semina automaticamente con il timestamp corrente, quindi si ottengono sempre gli stessi valori poiché si crea costantemente una nuova istanza dell'oggetto Random.

Modifica: Inoltre, è possibile provare questo, anche se non è sicuramente l'ideale. Preferirei una singola istanza Random o un seme statico su questo metodo.

Random r = new Random(Guid.NewGuid().GetHashCode()); 
+0

sarebbe possibile creare una nuova istanza della classe Random all'interno della funzione ricorsiva e passare un timestamp? –

+0

@SianJakeyEllis è possibile creare un seme globale (statico) e riutilizzarlo nel costruttore durante la creazione degli oggetti casuali. Tuttavia, questo è probabilmente un po 'meno di efficienza ideale saggio. –

2

Sarebbe utile se hai postato il codice. Ma, in assenza di questo, userò i miei poteri psichici e immagino che si sta utilizzando un modello come questo

void MyRecursiveFunction() { 
    var index=new Random().Next(...); 
    ... 
} 

Se fosse vero, la correzione è quello di modificare il codice in modo che lo fa "new Random()" solo una volta e lo passa in giro (o lo memorizza in una opportuna variabile d'istanza) anziché costruirne uno nuovo ogni volta.

1

Passare il Random come parametro alla funzione ricorsiva e utilizzare l'istanza passata per ottenere ogni volta il valore successivo da esso.

public void Recurse(object param, Random rand) 
{ 

    ... 
    var val = rand.Next(); 
    //use the value ... 
    Recurse(obj, rand); 
} 

Recurse(arg, new Random()); 

Ovviamente, la ricorsione avrà il minimo in qualche modo, ma questo dimostra il principio.

0

Suggerisco di includere l'oggetto casuale nella funzione ricorsiva stessa. Questo test dovrebbe dimostrare che non si ottiene sempre lo stesso int.

[Test] 
    public void TestSpintaxRandom() 
    { 
     spintaxParser("{|||{|||{|||{|||{|||{|||{|||{|||}}}}}}}}", new Random()); 
    } 

    public String spintaxParser(String s, Random r) 
    { 
     if (s.Contains('{')) 
     { 
      var closingBracePosition = s.IndexOf('}'); 
      var openingBracePosition = closingBracePosition; 

      while (!s[openingBracePosition].Equals('{')) 
       openingBracePosition--; 

      var spintaxBlock = s.Substring(openingBracePosition, closingBracePosition - openingBracePosition + 1); 
      var items = spintaxBlock.Substring(1, spintaxBlock.Length - 2).Split('|'); 

      var next = r.Next(items.Length); 
      Console.WriteLine(next); 
      s = s.Replace(spintaxBlock, items[next]); 

      return spintaxParser(s, r); 
     } 

     return s; 
    } 
Problemi correlati