web-dev-qa-db-ja.com

Random.Nextは常に同じ値を返します

これは本当に奇妙で、なぜこれが起こっているのかわかりません。 foreachサイクルでは、クラスAコレクションを繰り返し処理し、クラスごとにCount()メソッドを呼び出します。ここで、r1およびr2番号は、範囲[-1,1]から生成されます。問題はそれです Random.Nextは、各インスタンスに対して同じ「乱数」を返します。最初のインスタンスの結果が0および-1の場合、次のインスタンスから同じ結果が返されます。なぜこれが起こっているのか教えてもらえますか?また、クラスAインスタンスごとに異なる結果を得ることができません。これはコードです:

class a
{
 Random rnd = new Random();
 private void Count()
 {
  int r1 = rnd.Next(-1, 1);
  int r2 = rnd.Next(-1, 1);
 }
}
class b
{
 List<a> listofA=new list<a>();
 foreach (a ACLASS in listofA)
 {
  ACLASS.Count();
 }
}
58
Thomas

問題は、時間的に近すぎるRandomクラスのインスタンスを作成していることです。

Randomオブジェクトを作成すると、システムクロックからの値がシードされます。時間的に近すぎるRandomインスタンスを作成すると、それらはすべて同じランダムシーケンスでシードされます。

単一のRandomオブジェクトを作成し、「a」インスタンスごとに1つのRandomオブジェクトを作成する代わりに、「a」クラスのインスタンスを作成するときにその参照をコンストラクターに渡します。

118
Guffa

Randomの新しいインスタンスを非常に密接に作成しているため(ループは非常にタイトです)、各インスタンスは同じシード値を効果的に使用しています。

より良い方法は、1つのインスタンスを作成し、それをCountメソッドに渡すことです。

次のビットを知っていると思いますが、完全を期すためにここに含めます。

[〜#〜] msdn [〜#〜] には詳細がありますが、基本的に問題は Random.Next を使用しているメソッドが生成することです:

MinValue以上、maxValue未満の32ビット符号付き整数。つまり、戻り値の範囲にはminValueは含まれますが、maxValueは含まれません。 minValueがmaxValueと等しい場合、minValueが返されます。

このため、呼び出しは-1または0を返します。

9
ChrisF

クラスのすべてのインスタンスに対して、単一の静的な乱数ジェネレーターを使用します。

class a
{
  private static Random rnd;
  static a() {
      rnd = new Random();
  }
  private void Count()
  {
    int r1 = rnd.Next(-1, 2);
    int r2 = rnd.Next(-1, 2);
  }
}

-1、0ではなく-1、1の範囲の数値を提供する変更に注意してください。

9
tvanfosson

各Aインスタンスにランダムインスタンスを含めます。彼らはすべて同じデフォルトのシード値を取得しているようです。おそらく、すべてのAインスタンスに対して静的ランダムを作成して繰り返し使用するか、AコンストラクターのRandom()インスタンスにシード値を提供する必要があります。

5
Jherico