15

このコードでは:

Random random = new Random(441287210);
for(int i=0;i<10;i++)
    System.out.print(random.nextInt(10)+" ");
}

出力は1 1 1 1 1 1 1 1 1 1、毎回です。

どうしてこれなの?あるべきじゃないRandom...うーん...ランダム?Randomクラスは を使用していると思ったSystem.nanoTimeので、出力は一般的にランダムになるはずです。誰か説明してくれませんか?

4

6 に答える 6

20

あと数枚印刷してみましょう。最初の 100 枚は

1 1 1 1 1 1 1 1 1 1 3 4 7 2 2 6 0 3 0 2 8 4 1 6 0 0 0 2 8 2 9 8 9 2 5 2 1 1 4 5 3 4 1 4 1
8 7 6 6 0 6 5 0 4 5 5 6 0 8 3 8 9 7 4 0 9 9 7 7 9 3 9 6 4 5 0 6 3 7 4 9 8 7 6 2 8 9 8 4 4
8 4 9 0 1 6 9 6 1 5

これは問題ないようです。

すべての適切な (疑似) ランダム シーケンスには、繰り返される数字のストリークが含まれます。これは 1 から始まります。

于 2012-11-05T23:19:24.923 に答える
14

Randomクラスによって生成される値は疑似乱数です。シード値に基づいて、決定論的アルゴリズムを使用して作成されます。通常(たとえば、パラメーターなしのコンストラクターを使用する場合)、シードは現在の時刻を使用して初期化されます。これは明らかに一意の値です。したがって、一意の「ランダム」シーケンスが生成されます。

ここでは、コードの実行間で変化しない定数シード値を使用しています。したがって、常に同じシーケンスが得られます。たまたま、このシーケンスが1 1 1 1 1 1 ...この特定のシード用です。

于 2012-11-05T23:19:08.020 に答える
5

連続した10 秒のシーケンスが不可能であることは言うまでもあり1ません。シード値を提供した人は、たまたま 10秒連続441287210で始まるような値を見つけただけです。1呼び出しを続けるとnextInt()(10 回以上)、ランダムな値が表示されます。他の「明らかにランダムではない」シーケンスになる他のシード値を見つけることができるはずです。

于 2012-11-05T23:20:53.290 に答える
3

Random は線形合同ジェネレーターです。つまり、次の形式の式に基づいています。

N <- (N * C1 + C2) % M

ここで、C1、C2、および M は定数です。

このクラスのジェネレーターの特性の 1 つは、自己相関が高いことです。実際、連続する数値をプロットすると、数値に明確な剥ぎ取りパターンが見られます。

テスト プログラムは、基礎となるジェネレーターから 10 個の連続した数値を効果的に取得し、それらの値を 10 を法として計算し、それらがすべて同じであることを発見しました。事実上、モジュロ 10 は発電機の自然な周期性と "共鳴" しています ... 短期間です。

これは、自己相関の高い PRNG を使用することの欠点の 1 つです。素人の言葉で言うと...「あまりランダムではない」...ランダム性が重要な状況で使用すると、問題が発生する可能性があります。


ノート:

  • Random は乱数ジェネレーターではありません。疑似乱数ジェネレーターです。つまり、初期状態がわかっている場合、生成される数値は完全に予測可能です。
  • ランダムに真のランダムシードを使用しても、実際には役に立ちません。問題の再現が難しくなるだけです。
  • この特定のテストで同様のパターンが得られる Random の他のシードがある可能性があります。
  • 純粋に数学的な観点からは、10 の 1 は、他の 10 の数列と同じように「ランダム」ではありません。しかし、数学的な観点からRandomは、まったくランダムではありません。実際、 の現在の値が何であるかがわかれば、完全に予測可能Nです。問題は、シーケンスが直感的に非ランダムに見える自己相関です。
  • この種の直感的な非ランダム性を回避したい場合は、真の乱数ソースであるか、予測がはるかに困難な疑似乱数のジェネレーターである SecureRandom を使用してください。
于 2012-11-05T23:32:03.633 に答える
1

を使用するfor(int i=0;i<100;i++)と、出力されるシーケンスは再び「よりランダム」になります。連続して 10 のランダムなシーケンスが発生する確率は1小さいかもしれませんが、不可能ではありません。(十分なサンプルが与えられている限り、どのシーケンスもほぼ確実に発生します。)

それは単に興味深い偶然です。

于 2012-11-05T23:20:35.883 に答える
0

Random class uses seed to generate random number when you call nextInt() and is advised to be a long number, when you are creating random object, you are providing an int which is not sufficient enough for randomness.

Try to run the loop for 20 times, you will see randomness or remove seed or provide a very long seed value

于 2012-11-05T23:27:22.020 に答える