Ho chiamato una classe QuickRandom
e il suo compito è produrre rapidamente numeri casuali. È davvero semplice: prendi il vecchio valore, moltiplica per a double
e prendi la parte decimale.
Ecco la mia QuickRandom
classe nella sua interezza:
public class QuickRandom {
private double prevNum;
private double magicNumber;
public QuickRandom(double seed1, double seed2) {
if (seed1 >= 1 || seed1 < 0) throw new IllegalArgumentException("Seed 1 must be >= 0 and < 1, not " + seed1);
prevNum = seed1;
if (seed2 <= 1 || seed2 > 10) throw new IllegalArgumentException("Seed 2 must be > 1 and <= 10, not " + seed2);
magicNumber = seed2;
}
public QuickRandom() {
this(Math.random(), Math.random() * 10);
}
public double random() {
return prevNum = (prevNum*magicNumber)%1;
}
}
Ed ecco il codice che ho scritto per testarlo:
public static void main(String[] args) {
QuickRandom qr = new QuickRandom();
/*for (int i = 0; i < 20; i ++) {
System.out.println(qr.random());
}*/
//Warm up
for (int i = 0; i < 10000000; i ++) {
Math.random();
qr.random();
System.nanoTime();
}
long oldTime;
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
Math.random();
}
System.out.println(System.nanoTime() - oldTime);
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
qr.random();
}
System.out.println(System.nanoTime() - oldTime);
}
È un algoritmo molto semplice che moltiplica semplicemente il doppio precedente per un doppio "numero magico". L'ho messo insieme abbastanza rapidamente, quindi probabilmente potrei renderlo migliore, ma stranamente, sembra funzionare bene.
Questo è l'output di esempio delle righe commentate nel main
metodo:
0.612201846732229
0.5823974655091941
0.31062451498865684
0.8324473610354004
0.5907187526770246
0.38650264675748947
0.5243464344127049
0.7812828761272188
0.12417247811074805
0.1322738256858378
0.20614642573072284
0.8797579436677381
0.022122999476108518
0.2017298328387873
0.8394849894162446
0.6548917685640614
0.971667953190428
0.8602096647696964
0.8438709031160894
0.694884972852229
Hm. Abbastanza casuale. In effetti, ciò funzionerebbe per un generatore di numeri casuali in un gioco.
Ecco un esempio di output della parte non commentata:
5456313909
1427223941
Wow! Esegue quasi 4 volte più velocemente di Math.random
.
Ricordo di aver letto da qualche parte ciò che Math.random
usava System.nanoTime()
e tonnellate di moduli folli e roba da divisione. È davvero necessario? Il mio algoritmo si comporta molto più velocemente e sembra abbastanza casuale.
Ho due domande:
- Il mio algoritmo è "abbastanza buono" (per esempio, un gioco in cui i numeri davvero casuali non sono troppo importanti)?
- Perché fa
Math.random
così tanto quando sembra solo una semplice moltiplicazione e il taglio del decimale sarà sufficiente?
new QuickRandom(0,5)
o new QuickRandom(.5, 2)
. Entrambi genereranno ripetutamente 0 per il tuo numero.