Saya membuat kelas yang dipanggil QuickRandom
, dan tugasnya adalah menghasilkan angka acak dengan cepat. Ini sangat sederhana: ambil saja nilai lama, kalikan dengan double
, dan ambil bagian desimal.
Inilah QuickRandom
kelas saya secara keseluruhan:
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;
}
}
Dan ini kode yang saya tulis untuk mengujinya:
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);
}
Ini adalah algoritma yang sangat sederhana yang hanya mengalikan ganda sebelumnya dengan "angka ajaib" ganda. Saya melemparkannya bersama dengan cukup cepat, jadi saya mungkin bisa membuatnya lebih baik, tetapi anehnya, itu sepertinya berfungsi dengan baik.
Ini adalah contoh keluaran dari baris komentar dalam main
metode:
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 Cukup acak. Bahkan, itu akan bekerja untuk generator angka acak dalam game.
Berikut adalah contoh output dari bagian yang tidak dikomentari:
5456313909
1427223941
Wow! Ia melakukan hampir 4 kali lebih cepat daripada Math.random
.
Saya ingat pernah membaca di suatu tempat yang Math.random
digunakan System.nanoTime()
dan banyak modulus dan hal-hal divisi gila. Apakah itu benar-benar perlu? Algoritma saya bekerja jauh lebih cepat dan sepertinya cukup acak.
Saya punya dua pertanyaan:
- Apakah algoritma saya "cukup baik" (untuk, mengatakan, permainan, di mana benar-benar nomor acak yang tidak terlalu penting)?
- Mengapa
Math.random
melakukan begitu banyak ketika tampaknya hanya perkalian sederhana dan memotong desimal sudah cukup?
new QuickRandom(0,5)
atau new QuickRandom(.5, 2)
. Keduanya akan menghasilkan 0 untuk nomor Anda berulang kali.