3

最後の段落をシャッフルするフィッシャー・イェーツに関するウィキペディアのページを読むと、次のようになります。

最後に、完全な乱数生成を使用しても、ジェネレーターの不適切な使用によって実装に欠陥が導入される可能性があることに注意してください。たとえば、Java 実装が、コンストラクター引数を渡さずに、シャフラーへの呼び出しごとに新しいジェネレーターを作成するとします。ジェネレーターは、言語の時刻 (Java の場合は System.currentTimeMillis()) によってデフォルトでシードされます。したがって、2 人の呼び出し元がクロックの粒度 (Java の場合は 1 ミリ秒) よりも短いタイムスパン内でシャフラーを呼び出した場合、それらが作成するジェネレーターは同一になり、(同じ長さの配列の場合) 同じ置換が行われます。生成されます。これは、シャフラーが立て続けに何度も呼び出された場合にほぼ確実に発生し、そのような場合に非常に不均一な分布につながります。異なるスレッドからの独立した呼び出しにも適用できます。より堅牢な Java 実装では、シャフラー関数の外部で定義されたジェネレーターの単一の静的インスタンスを使用します。

この段落の最後の文以外はすべて理解しています。著者が次のように言うとき、どういう意味ですか。

より堅牢な Java 実装では、シャフラー関数の外部で定義されたジェネレーターの単一の静的インスタンスを使用します。

4

4 に答える 4

12

これは、次のような単一の静的関数があることを意味します。

class RandomUtil {

    public static final Random rand = new Random();     

}

次に、この rand ジェネレーターRandomUtil.rand.nextInt()を使用して、すべての乱数を生成します。この 1 つのインスタンスのみを使用し、wiki に記載されている問題が発生しないようにします。

于 2012-07-04T06:10:29.590 に答える
4

その記事の一部が間違っています:

たとえば、Java 実装が、コンストラクター引数を渡さずに、シャフラーへの呼び出しごとに新しいジェネレーターを作成するとします。ジェネレーターは、言語の時刻 (Java の場合は System.currentTimeMillis()) によってデフォルトでシードされます。したがって、2 人の呼び出し元がクロックの粒度 (Java の場合は 1 ミリ秒) よりも短いタイムスパン内でシャフラーを呼び出した場合、それらが作成するジェネレーターは同一になり、(同じ長さの配列の場合) 同じ置換が行われます。生成されます。

これは実際には正しくありません。呼び出しごとに新しいジェネレーターを作成するのはお勧めできませんが、Randomクラスにはこれを防ぐためのコードが含まれています。

 public Random() {
     this(++seedUniquifier + System.nanoTime());
 }
 private static volatile long seedUniquifier = 8682522807148012L;

まず、分解能は1 ミリ秒ではなく1ナノ秒です。ジェネレーターを作成して一度使用すると、通常は 1 ナノ秒以上かかります。第二に、そうでない場合でも、seedUniquifier値は呼び出しごとに異なります。

そのため、呼び出しごとに new を生成することは依然として悪い考えですがRandom、その記事が示唆しているよりも多少害は少なくなります。

于 2012-07-04T08:11:41.787 に答える
2

同じシードと同じ順列を使用する 2 つの乱数ジェネレーターは、1 つのジェネレーターを使用して異なる乱数を生成するよりもランダム性が低くなる可能性があります。

同時に 2 つのデフォルトの乱数ジェネレーターを作成したとします。タイムスタンプ (ミリ秒) をシードとして使用します。そして、同じ順列を持つでしょう。ここで、2 つの異なるジェネレーターから最初の乱数を取得しようとしますが、それらは同じになる可能性があります。

このような状況を回避するには、public static final Random変数を作成してどこでも使用します。

于 2012-07-04T06:11:01.333 に答える
0

この実装を堅牢にし、予測可能な乱数を生成しないようにするには、ジェネレーター クラスをシャフラー クラスの外部の静的メソッドで定義する必要があります。したがって、ジェネレーターの 2 つ以上のオブジェクトが常に作成されることはありません。したがって、同じ乱数を生成する可能性を最小限に抑えます。

于 2012-07-04T06:15:00.103 に答える