というクラスを作成しましたQuickRandom
。その仕事は、乱数をすばやく生成することです。それは本当に簡単です。古い値を取り、を掛けてdouble
、小数部分を取ります。
ここに私のQuickRandom
クラス全体があります:
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;
}
}
そして、これは私がそれをテストするために書いたコードです:
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);
}
これは、前のdoubleに「マジックナンバー」のdoubleを単純に乗算する非常に単純なアルゴリズムです。私はそれをかなり速く一緒に投げたので、私はおそらくそれをより良くすることができましたが、奇妙なことに、それはうまく機能しているようです。
これは、main
メソッド内のコメント化された行の出力例です。
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
うーん。かなりランダム。実際、これはゲームの乱数ジェネレーターで機能します。
以下は、コメントアウトされていない部分の出力例です。
5456313909
1427223941
うわー!パフォーマンスは、の約4倍ですMath.random
。
クレイジーモジュラスやディビジョンなどのMath.random
使用されているものSystem.nanoTime()
をたくさん読んだことを覚えています。それは本当に必要ですか?私のアルゴリズムははるかに速く実行され、かなりランダムに見えます。
2つの質問があります。
- 私のアルゴリズムは「十分」であるか(たとえば、本当に乱数がそれほど重要ではないゲームの場合)?
Math.random
単純な乗算と小数の切り取りで十分だと思われるのに、なぜそんなに多くのことをするのですか?
new QuickRandom(0,5)
またはを試してくださいnew QuickRandom(.5, 2)
。これらは両方とも、番号に対して0を繰り返し出力します。