2013-04-29 20 views
7

Stavo cercando di spiegare il generatore di numeri casuali in Java a un amico quando continuava a ricevere gli stessi numeri ogni volta che eseguiva il programma. Ho creato la mia versione più semplice della stessa cosa e anche io ottengo gli stessi numeri esatti che riceveva ogni volta che eseguivo il programma.I numeri casuali di Java non sono casuali?

Cosa sto sbagliando?

import java.util.*; 

public class TestCode{ 
    public static void main(String[] args){ 
     int sum = 0; 
     Random rand = new Random(100); 
     for(int x = 0; x < 100; x++){ 
      int num = (rand.nextInt(100)) + 1; 
      sum += num; 
      System.out.println("Random number:" + num); 
     } 
     //value never changes with repeated program executions. 
     System.out.println("Sum: " + sum); 
    } 

} 

Gli ultimi cinque numeri su 100 sono:

40 
60 
27 
56 
53 
+1

credo sia un uso migliore modo Math.random(). – Gere

+6

Stai utilizzando un seme costante durante la creazione dell'istanza Casuale. Quindi ovviamente avrai gli stessi numeri. –

+3

@Gere: cosa c'è di così magico in 'Math.random()' e perché è meglio che usare un'istanza Random? –

risposta

23

Si hanno seminato il generatore casuale con un valore costante 100. È deterministico, quindi genererà gli stessi valori a ogni esecuzione.

non so il motivo per cui si è scelto di seminare con 100, ma il valore del seme non ha nulla a che fare con l'intervallo di valori che vengono generati (che è controllata con altri mezzi, come ad esempio la chiamata a nextInt che già avere).

Per ottenere valori diversi ogni volta, utilizzare il costruttore Random senza argomenti, che utilizza l'ora del sistema per eseguire il seeding del generatore casuale.

Citando Javadoc per il costruttore senza parametri Random:

creare un nuovo generatore di numeri casuali. Questo costruttore imposta il seme del generatore di numeri casuali su un valore molto probabilmente distinto da da qualsiasi altra chiamata di questo costruttore.

Citando il codice vero e proprio in senza parametri Random costruttore:

public Random() { 
    this(seedUniquifier()^System.nanoTime()); 
} 
2

questo:

Random rand = new Random(100); 

Stai dando il generatore di numeri casuali lo stesso seme (100) ogni volta che si avvia il programma. Dagli qualcosa come l'output di System.currentTimeMillis() e questo dovrebbe darti numeri diversi per ogni chiamata.

1

I generatori di numeri casuali sono in realtà solo pseudo-casuali. Cioè, usano mezzi deterministici per generare sequenze che appaiono casuali in base a determinati criteri statistici.

Il constatore Random(long seed) consente di passare un seme che determina la sequenza di numeri pseudo-casuali.

0

Spero che questo aiuti ..

Random r = new Random(System.currentTimeMillis()); 
double[] rand = new double[500]; 
for(int i=0;i<100;i++){ 
    rand[i] = r.nextDouble(); 
    //System.out.print(rand[i] + "\n"); 
} 
//System.out.println(); 
return rand[randomInt];