2011-06-24 18 views
1

新しいRandom()で静的最終ランダムオブジェクトをインスタンス化して同じシードを使用していると仮定すると、同じインスタンス内でnextBytesを呼び出すことによって同じ番号を2回取得できますか?Java Randomクラスは、同じシードとnextBytes()を使用して重複数を生成しますか?

私は、任意の種のために、すべての可能な「ランダム」番号を決定することができることを知っていますし、それはより多くのシーケンス本当に好きです。私はこのコードを持っているのであれば、基本的

synchronized protected int next(int bits) { 
    seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); 
    return (int)(seed >>> (48 - bits)); 
} 

private static final Random random = new Random(); 

public void doSomething() { 
    for (int i=0; i < 1000000000; i++) { 
     byte byteArray[] = new byte[8]; 
     random.nextBytes(byteArray) 
    } 
} 

生成可能なすべての数値を調べる前に、nextBytesが同じバイトを生成する可能性はどれくらいですか。

これは、指定されたビットのすべての可能な組み合わせを返す前に同じ値を返しますか?はい、私は推測していますが、これはどのくらいの頻度で起こりますか?

答えて

5

クラスRandomは、非常に長い周期の線形合同ジェネレータを使用します。非常に長い間int値を繰り返すことはありません。 nextBytesを8バイト配列で呼び出すと、2つのint値が生成され、4つの8ビット値に分割されて配列が満たされます。

nextBytesを連続して呼び出しても同じ値が生成されるとは限りません。これは、乱数ジェネレータの周期が2であることを意味します。docsは、これを不可能にするnextの特定の動作を指定します。 (Randomのサブクラスは、もちろん、あなたが好きな病理学的行動のいずれかの種類を持つことができますが、java.util.Randomのインスタンスは行儀されます。)

+0

期間によって、最終的にその種子が元の値になることを意味しますか?もちろん、正確に同じ数を再度生成しますか?例えば、java.util.Randomで1から1000までの乱数を生成している場合、与えられた数を生成する確率は0か1/1000よりも何か高いですか? –

+1

それは正しいです。 java.util.Randomによって生成される数値シーケンスは、シードが設定されると完全に確定的です。それが_pseudo_ randomと呼ばれる理由です。次の1000個の数字に存在する所定の数字の「確率」は、0または1のいずれかです。これを予測することは非常に困難であり、統計的な目的のために数字がランダムである場合に動作します。より強力な乱数ジェネレータについては、 'java.security.SecureRandom'クラスを見てください。 –

0

nextBytesが前の繰り返しで返した値と同じ値を返す確率は、nextBytesが特定のランダムな8バイトを返す確率とまったく同じです。

良い乱数生成器は、ビットがランダムであるという事実以外に返されるビットを保証しません。場合によっては、ジェネレータがすべての可能な値をランダムな順序で返すようにすることが望ましい場合もありますが、通常はランダムジェネレータの目標ではありません。

+0

これは私が期待したとおりです、ありがとうございます。 –

+1

これは間違っています。 'java.util.Random'は真の乱数ジェネレータではありません。非常に長い周期を有する擬似ランダム線形合同生成器である。シードがリセットされない限り、連続した呼び出しで同じ値を持つ8バイトの配列を埋めることはできません。それは2の期間を与え、それはドキュメントで指定された動作に反します。 –

+0

ありがとうございます。私はjava.util.Randomがランダムであると仮定しましたが、ドキュメントを読んだ後は明らかにそうではありません。 –

0

繰り返し同じ値が発生することができないことを示唆している上記の答えは、そのJavaのを忘れているように見えます.Randomの期間は2^48です。そのため、nextInt()は、RNGの期間内にすべての値を処理する前に完全に同じ整数を生成する可能性があります。 2^16回、実際に。

また、整数が4つに分割されているので、すべての整数を渡す必要があっても、同じバイトが表示される可能性があります。実際には、そうであれば、すべての整数値を調べる前に、すべてのバイト値が2^24回表示されます。私は、元の質問は8バイトからなるバイト配列に関係していることを認識しています。このケースでは、2^31(2^47のJavaのランダム)呼び出しの後で同じ配列をnextByteに呼び出します(2つの整数が必要なため)。

私が前に言ったように、すべての整数を調べる必要はありません。

nextInt()によって返される値の一様分布を仮定すると、一連のnサンプルで正確に同じ整数を得る確率は、 約1 - ((2^32 -1 )/ 2^32)^(n(n-1)/ 2)となる。http://en.wikipedia.org/wiki/Birthday_problem

2つの一致する整数を持つ確率が50%を超えるように描画する必要があるサンプルの数は、77000をわずかしか超えていません。 2つの2^32の整数(8バイトの場合)では、5 * 10^9サンプル後に同じ確率が得られます。これは約2^32です。その時までにすべての整数を見ることができたとしても、これはRandomの期間よりもかなり短いことに注意してください。真実は恐らくおそらくその中間です。とにかく、確率は非常に低いですが、上記の投稿で示唆されているように完全にゼロではありません。

私に何か不足していますか?

関連する問題