これは何?
Javaの乱数生成器について速度面から調査してみる
という記事を見て、Java の乱数にも色々あるんだなと思い。
速度面以外を軽く調べた。
調べた
java.util.Random
Knuth 先生の有名なアルゴリズムを使っている。
有名だけど、メルセンヌ・ツイスタなんかと比べるとバラケ具合がしょぼいこともよく知られている。
java.util.concurrent.ThreadLocalRandom
内部状態は
long rnd;
の一個、64bit だけ。定数が
long multiplier = 0x5DEECE66DL;
long addend = 0xBL;
long mask = (1L << 48) - 1;
と用意されていて計算は
int next(int bits) {
rnd = (rnd * multiplier + addend) & mask;
return (int) (rnd >>> (48-bits));
}
これだけ。bits はほしいビット数なので気分としては 32固定だと思っていいと思う。
実用的には困らない場面も多いとは思うけど、バラケ具合はあまり良くないと思う。
L??X??MixRandom
L32X64MixRandom のソースコードらしきもの を見ると
LXM ファミリの一員らしい。
M
は、0xadb4a92d
という値。
a
は、コンストラクタで決まる奇数で。
xoroshiro64 で作られた乱数 x0 と、と $s=Ms+a$ で作られる系列 s
の値を足したものを
public static int mixLea32(int z) {
z = (z ^ (z >>> 16)) * 0xd36d884b;
z = (z ^ (z >>> 16)) * 0xd36d884b;
return z ^ (z >>> 16);
}
で混ぜたものらしい。
単なる xoroshiro64 だと弱いので別の乱数を混ぜた感じかな。
Xoroshiro128PlusPlus
中身は見てないけど、Xoroshiro128++ なんだろう。
Xoroshiro シリーズは https://prng.di.unimi.it/ を読むとなんだか分かる。
Xoshiro256PlusPlus
中身は見てないけど、Xoshiro256++ なんだろう。
Xoroshiro シリーズと同様、 https://prng.di.unimi.it/ を読むとなんだか分かる。
感想
メルセンヌ・ツイスタが無いのがちょっと意外。
最初に上げた記事では
個人的には、暗号やセッションキーの生成等ではSecureRandom。それ以外は通常ThreadLocalRandom。
となっているけど、私なら
- 予測不能性が必要ない場面なら基本
Xoroshiro128PlusPlus
またはXoshiro256PlusPlus
。どっちか速い方。どっちが速いか知らない今調べずに使うならXoshiro256PlusPlus
かな。 - $2^{256}$ より長い周期が必要になったら LXM ファミリから選ぶ
かな。
とはいえ。
Java を使う機会自体がないのであった。