Ich habe eine Klasse namens erstellt QuickRandom
, deren Aufgabe es ist, schnell Zufallszahlen zu erzeugen. Es ist ganz einfach: Nehmen Sie einfach den alten Wert, multiplizieren Sie ihn mit a double
und nehmen Sie den Dezimalteil.
Hier ist meine QuickRandom
Klasse in ihrer Gesamtheit:
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;
}
}
Und hier ist der Code, den ich geschrieben habe, um ihn zu testen:
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);
}
Es ist ein sehr einfacher Algorithmus, der einfach das vorherige Doppel mit einem "magischen Zahlen" -Doppel multipliziert. Ich habe es ziemlich schnell zusammengeschmissen, also könnte ich es wahrscheinlich besser machen, aber seltsamerweise scheint es gut zu funktionieren.
Dies ist eine Beispielausgabe der auskommentierten Zeilen in der main
Methode:
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. Ziemlich zufällig. Tatsächlich würde das für einen Zufallszahlengenerator in einem Spiel funktionieren.
Hier ist eine Beispielausgabe des nicht auskommentierten Teils:
5456313909
1427223941
Beeindruckend! Es arbeitet fast viermal schneller als Math.random
.
Ich erinnere mich, dass ich irgendwo etwas gelesen habe, das Math.random
gebraucht wurde, System.nanoTime()
und jede Menge verrücktes Modul- und Teilungsmaterial. Ist das wirklich notwendig? Mein Algorithmus arbeitet viel schneller und scheint ziemlich zufällig zu sein.
Ich habe zwei Fragen:
- Ist mein Algorithmus „gut genug“ (für, sagen wir, ein Spiel, wo wirklich zufällige Zahlen sind nicht so wichtig)?
- Warum macht
Math.random
man so viel, wenn es so aussieht, als würde eine einfache Multiplikation und das Ausschneiden der Dezimalstelle ausreichen?
new QuickRandom(0,5)
oder new QuickRandom(.5, 2)
. Diese geben beide wiederholt 0 für Ihre Nummer aus.