2011-01-27 26 views
7

可能性の重複:
Why does this Random Number Generator not random?ランダム()ランダムではないのはなぜですか?

私は、このテストプログラムがあります:私はSystem.Threading.Thread.Sleep(1);をコメントアウトした場合、私は

を得る

static void Main(string[] args) 
{ 
    var randomNumbers = new Dictionary<int, int>(); 
    foreach (var s in Enumerable.Range(1, 500)) 
    { 
     var rand = Rand5(); 
     if (!randomNumbers.ContainsKey(rand)) 
      randomNumbers.Add(rand, 1); 
     else 
      randomNumbers[rand] += 1; 
    } 

    randomNumbers 
     .ToList() 
     .ForEach(x => Console.WriteLine("{0}: {1}", x.Key, x.Value)); 
    Console.ReadLine(); 
} 

static int Rand5() 
{ 
    System.Threading.Thread.Sleep(1); 
    return new Random().Next(1, 6); 
} 



5: 500 

しかし、その行のコメントを外すと、乱数が得られます。

2: 87 
4: 94 
1: 116 
5: 108 
3: 95 

なぜコード行が問題になるのですか?ありがとう!それは数字を生成するためのシードとしてクロックを使用していますし、あなたがそのように乱数を生成するとき、あなたは乱数発生器は、システムクロックに部分的に基づいて

+0

おそらく、すべての*ランダム*タグ付けされた質問の約3分の1が同じ問題ですので、それは二重引用符などの問題をマークするのは無駄だと思います。 – Joey

答えて

10

他の人が言ったように、現在のシステム時刻からnew Random()シードの乱数発生器。

私はan articleにこれを詳しく説明しています。これは、問題の解決策を示していますが、役に立つかもしれません。基本的には、Randomの同じインスタンスを複数回使用したいと考えていますが、ではなく、スレッドセーフです。

+0

詳細な解答をありがとう。ちなみに、私は深さ2であなたのC#を読んでいます:) – bla

+0

うわー、それは素晴らしい記事です。私は10分前よりも問題をよく理解しています。 –

+0

これは、私が 'System.Random'を静的なシングルトンで怠惰に初期化したかった理由です。 –

3

素早くそれらを突き出す...

2

同じ番号を取得し、C#はあまりにある原因

11

Randomタイプは、現在のシステム時間に応じてデフォルトで設定されます。これは、細かい粒度を持っています。

new Random().Next(1, 6)を何度も連続して呼び出すと、同じシード値を持つ多くのオブジェクトが構築され、同じ結果が得られます。 Thread.Sleep(1)は、単純に構造体を時間的に離して配置することでこの問題を解決し、異なるシード値の確率を高めます。

あなたは次の1つの呼び出しから特定のRandomオブジェクトを保持する必要があります。

var randomNumbers = new Dictionary<int, int>(); 
var random = new Random(); // Re-use this, don't keep creating new ones. 
foreach (var s in Enumerable.Range(1, 500)) 
{ 
    var rand = random.Next(1, 6); 
    // ... 
1

あなたがランダムをシードしていない場合、あなたはランダムと同じ番号を取得するにはのThread.sleepを使用することにより

擬似乱数生成器である(1)あなたはタイマーを進めるために、新たなを生成することを可能にします自動生成シード。

「修正する」方法は、1つのランダムオブジェクトを作成し、それを再利用する(他のものも回答したように)か、別のランダムジェネレータを使用することです。 http://msdn.microsoft.com/en-us/library/ctssatww.aspx

0

詳細情報あなたが使用するすべての乱数生成器は、擬似乱数です。これは、常に定義済みのシード値を持ち、テストには適していますが、真のランダム性のフィーチャを実装するのには適していません。

乱数を生成するには擬似乱数シーケンスを使用するか、最良の乱数を生成するためにはマルコフチェーンを使用することをお勧めします。これらのランダム関数のいずれかを使用する予定がある場合、真のランダム性に近いものはありません。

関連する問題