Domanda Generazione della stessa sequenza di numeri casuali


Voglio generare numeri casuali in java, so che dovrei usare metodi esistenti come Math.random (), tuttavia, la mia domanda è: come posso generare la stessa sequenza di numeri, ogni volta che eseguo la mia applicazione? esempio: la sequenza generata è: 0.9, 0.08.0.6 quindi voglio che questa sequenza venga generata ogni volta che eseguo questo metodo ..


17
2017-10-26 11:44


origine


risposte:


Certo, crea solo un'istanza di Random invece di usare Math.random()e specifica sempre lo stesso seme:

Random random = new Random(10000); // Or whatever seed - maybe configurable
int diceRoll = random.nextInt(6) + 1; // etc

Nota che diventa più difficile se la tua applicazione ha più thread coinvolti, poiché i tempi diventano meno prevedibili.

Questo sfrutta Random essere un generatore di numeri pseudo-casuali - In altre parole, ogni volta che lo chiedi per un nuovo risultato, manipola lo stato interno per darti una sequenza dall'aspetto casuale, ma conoscendo il seme (o lo stato interno corrente) è del tutto prevedibile.


30
2017-10-26 11:45



Un esempio di utilizzo ripetuto dello stesso seme.

public static void main(String... args) throws IOException {
    printDoublesForSeed(1);
    printDoublesForSeed(128);
    printDoublesForSeed(1);
    printDoublesForSeed(128);
}

private static void printDoublesForSeed(long seed) {
    double[] doubles = new double[10];
    Random rand = new Random(seed);
    for (int j = 0; j < doubles.length; j++) {
        doubles[j] = (long) (rand.nextDouble() * 100) / 100.0;
    }
    System.out.println("doubles with seed " + seed + " " + Arrays.toString(doubles));
}

stampe

doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93]
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47]
doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93]
doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47]

EDIT Un interessante abuso di semi casuali.

public static void main(String ... args) {
    System.out.println(randomString(-6225973)+' '+randomString(1598025));
}

public static String randomString(int seed) {
    Random rand = new Random(seed);
    StringBuilder sb = new StringBuilder();
    for(int i=0;i<5;i++)
        sb.append((char) ('a' + rand.nextInt(26)));
    return sb.toString();
}

stampe

hello world

26
2017-10-26 11:51



È necessario seminare il generatore di numeri casuali.

Random random = new Random(aFixedNumber);
random.nextInt();  // will always be the same

6
2017-10-26 11:46



Math.random è solo un wrapper della classe java.util.Random. La prima volta che chiami Math.random un'istanza della classe java.util.Random è creato.

Ora, la maggior parte delle API non ne espone alcuna vero  generatori di numeri casuali, perché non possono essere implementati nel software. Invece, usano pseudo-casuale generatori di numeri, che generano una sequenza di numeri dall'aspetto casuale usando un mucchio di formule. Questo è ciò java.util.Random lo fa. Tuttavia, ogni generatore di numeri pseudo casuali deve essere seminato primo. Se hai due generatori di numeri pseudo casuali che usano lo stesso algoritmo e usano lo stesso seme, produrranno lo stesso risultato.

Di default, java.util.Random usa i millisecondi dal 1 ° gennaio 1970 come seme. Pertanto, ogni volta che avvii il tuo programma, produrrà numeri diversi (a meno che tu non lo gestisca per avviare java in meno di 1 millisecondo). Quindi, la soluzione al tuo problema è creare il tuo java.util.Random istanza e semina da solo:

import java.util.Random;

class ... {
    Random randomNumberGenerator = new Random(199711);

    public void ...()
    {
        int randomInt = randomNumberGenerator.nextInt();
        double randomDouble = randomNumberGenerator.nextDouble();
    }
}

Il randomNumberGenerator sputerà sempre la stessa sequenza di numeri, a patto che non cambi il seme (il 199711).


4
2017-10-26 11:53



Inserirò i codici nell'app. Questo richiede più memoria ma è molto più veloce.

Basta stampare numeri casuali sul terminale, quindi copiarli e incollarli sul tuo codice.

Assicurati di lasciare un commento che spieghi cosa hai fatto, o sembreranno magia nera al lettore disinformato.


0
2017-10-26 16:56