1

私は C# を学習しており、プログラム内に乱数ジェネレーターを保持するクラスを作成しました。

class RandomNumberGenerator
{
    Random RNG = new Random();
    // A bunch of methods that use random numbers are in here
}

このクラス内には、RNG を使用するいくつかのメソッドがあります。データは、プログラムの他の部分からここに送信され、処理されてから返されます。メソッドの 1 つは、次のことを行います。

// Method works something like this
int Value1 = RNG.Next(x, y);
int Value2 = RNG.Next(x, y);
int Value3 = RNG.Next(x, y);

、値はxy別のクラスからここに送信されます。そのため、そのクラス内に のインスタンスを作成して、RandomNumberGeneratorそのメソッドを呼び出して x 値と y 値を渡す必要があります。

class DoStuff
{
    RandomNumberGenerator Randomizer = new RandomNumberGenerator
    // Here I call a bunch of Randomizer methods that give me values I need
}

上記の方法の問題は、3 つの値すべてに対して毎回同じ数値が得られることです。それらが非常に近くにあり、のシード値が変更される時間がないためか、クラスRandomizerの新しいインスタンスを作成するときに何か間違ったことをしているためかどうかはわかりません。RandomNumberGenerator

私はすでにここで多くの回答を調べてきましたが、通常、このような問題は、Randomメソッドを実行するときに多くの新しいオブジェクトを作成する人々によるものです (したがって、それらすべてのシードを同じ値に設定します) が、Random私が唯一の新しいオブジェクトcreate はRandomNumberGeneratorクラス内にあります。次に、それを他のクラス内でインスタンス化して、データを渡し、そのメソッドを使用できるようにします。

なぜこれが起こっているのですか?どうすれば修正できますか?

4

2 に答える 2

1

一般に、 の 1 つの静的インスタンスをRandom用意し、その 1 つのインスタンスを使用してアプリケーションのすべての乱数を取得する必要があります。lock複数のスレッドから使​​用する場合は、必ず確認してください。

于 2012-11-03T22:44:51.737 に答える
1

DoStuffループ内のインスタンスを作成していると思います。

呼び出しが速すぎると、複数のランダム インスタンスが同一のシードを生成し、同じ数が発生します。

for ループの外側で一度宣言するか、メソッドに渡します。

    Random r = new Random();
    for (int i = 0; i < count; i++)
    {
        // use the same random instance
    }

MSDNから:

乱数の生成はシード値から始まります。同じシードを繰り返し使用すると、同じ一連の数値が生成されます。異なるシーケンスを作成する 1 つの方法は、シード値を時間依存にすることです。これにより、Random の新しいインスタンスごとに異なるシリーズが作成されます。既定では、Random クラスのパラメーターなしのコンストラクターはシステム クロックを使用してシード値を生成しますが、パラメーター化されたコンストラクターは現在の時間の目盛り数に基づいて Int32 値を取ることができます。ただし、クロックの分解能は有限であるため、パラメーターなしのコンストラクターを使用して異なる Random オブジェクトを連続して作成すると、同一の乱数シーケンスを生成する乱数ジェネレーターが作成されます。

于 2012-11-03T22:46:36.740 に答える