クラスjava.util.Randomを使用する場合、メソッドnextInt()をN回呼び出すことで得られる値を、はるかに効率的な方法で(具体的にはO(1)で)取得するにはどうすればよいですか?
たとえば、特定のシード値を使用してRandomオブジェクトを作成し、100,000番目の「nextInt()値」(つまり、メソッドnextInt()を100,000回呼び出した後に取得した値)を高速に取得したい場合、私はそれをすることができますか?
簡単にするために、JDKのバージョン1.7.06を想定します。これは、クラスRandomの一部のプライベートフィールドの正確な値を知る必要がある場合があるためです。そして、と言えば、ランダムな値の計算に関連する次のフィールドが見つかりました。
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
ランダム性について少し調べたところ、線形合同法を使用してランダム値が取得されることがわかりました。アルゴリズムを実行する実際のメソッドは、メソッドnext(int)です。
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
アルゴリズムに関連する行は、次のシード値を取得する行です。
nextseed = (oldseed * multiplier + addend) & mask;
それで、より具体的には、この式を一般化して「n番目の次のシード」値を取得する方法はありますか?ここでは、それを取得した後、変数「ビット」を32にすることでn番目のint値を取得できると想定しています(メソッドnextInt()は単にnext(32)を呼び出し、結果を返します)。
前もって感謝します
PS:おそらく、これはmathexchangeに適した質問ですか?