2011-01-31 26 views
10

重複の可能性が返されました:
c# - getting the same random number repeatedly
Random number generator not working the way I had planned (C#)乱数生成同じ番号は

私はint型のキューを構築する方法があります:

public Queue<int> generateTrainingInts(int count = 60) 
    { 
     Queue<int> retval = new Queue<int>(); 

     for (int i = 0; i < count; i++) 
     { 
      retval.Enqueue(JE_Rand.rInt(2001, 100)); 
     } 

     return retval; 
    } 

JE_Rand .rInt()は、delegat私はgenerateTrainingIntsを呼び出すときに毎回同じ番号がエンキューされます。しかし、rIntを、ローカルインスタンス(上記で定義した関数スコープ)の代わりにRandomクラスの静的インスタンスを使用するように変更すると、正しく動作するように見えます(ランダムな整数をエンキューします)。誰がなぜこれが起こるのか知っていますか?

編集: 私の質問を完全に読まなかった回答者 あなたが指摘したように、私はなぜこのようなことが起こるのかをよく説明しています。私は同じ数字で生成された問題の解決法を探しているわけではありません。あなたの熱意に感謝します:)私は最初の実装が概念的に私にとって意味をなさされたので、本当にこのようなことを理解したいだけです。

+0

-httpようrealted質問を見てください...重複しているようだ://stackoverflow.com/questions/1437825/random-number-generation-in-c –

+0

'Random'オブジェクトが初期化されたので、それが起こります'環境。GetTickCount'は、ミリ秒タイマーである。つまり、同じ乱数の中で 'Random'コンストラクタを2回呼び出すと、同じ初期値を得ることになります。 –

+0

randが同じシードでインスタンス化されると(たとえば、あなたのケースではDateTime.Now.Millisecond)、同じシーケンスの値が返されます。一度インスタンス化して(静的変数に格納する)、または毎回異なるシードを使用する必要があります。 – AFract

答えて

23

同じRandomオブジェクトを保持する必要があります。静的メンバ

private static Random rand = new Random(); 

public static int rInt(int exclUB, int incLB = 0) 
{ 
    int t = rand.Next(incLB, exclUB); 
    return t; 
} 

編集
としてあなたの静的メソッドの外クロックの有限解像度がRandomを初期化するために使用されている理由は、それを入れてください。後続のRandomの初期化は、ランダムシーケンスで同じ開始位置を取得します。同じRandomを再利用する場合、ランダムシーケンスの次の値が常に生成されます。

+0

OPはそれをもう一度試して、* why *を求めていました。 –

+0

生成後にrandをnullに割り当てる理由randは非常に短時間でインスタンス化されるので、両方のインスタンスは同じシードを取得し、同じ値を返します。これは著者のバージョンとまったく同じです。それを静的に置き、常に同じインスタンスを保持する必要があります。 "Guid.NewGuid()。GetHashCode()"をシードとして使用するなど、さまざまなシードで複数のインスタンスを使用することもできますが、ひどいパフォーマンスが得られます。 – AFract

+0

コードサンプルを修正しました。これはボグスでしたが、今はうまくいくはずです... – AFract

5

は、次のコードを試してみてください、私はなぜあなたが見ると思う:Randomオブジェクトが何度も同じシードを取得している

void PrintNowAHundredTimes() 
{ 
    for (int i = 0; i < 100; ++i) 
    { 
     Console.WriteLine(DateTime.Now); 
    } 
} 

。これは、DateTime.Nowによって返されるシステム時間の細分性が非常に単純で有限であるためです。例えば私のマシンでは、値は15msごとにしか変化しません。その時間内に連続して呼び出すと、同じ時間が返されます。

あなたがすでに知っていると思うように、同じシード値で2つのRandomオブジェクトを初期化すると、同じランダムシーケンスが生成されます。 (それは技術的には、擬似ランダムと呼ばれる理由です。)

するとあなたはまた、それはあなたのメソッド内でローカルに新しいRandomオブジェクトをインスタンス化する意味があった場合でも、ということに注意する必要があり、いったんまだ(何の目的を果たしていないでしょうnullに設定しますメソッドは終了しますが、とにかくオブジェクトへの参照がなくなるため、関係なくガベージコレクションされます)。

1
public class JE_Rand 
{ 
    private static Random rand= new Random(DateTime.Now.Millisecond); 

    public static int rInt(int exclUB, int incLB = 0) 
    { 
     int t = rand.Next(incLB, exclUB); 
     return t; 
    } 
} 
+0

なぜrand = nullですか?それはオブジェクトをダンプし、次の呼び出しは例外をスローします – walter

+0

@walter:これは古い回答ですが、コードをコピーして貼り付け、メソッド呼び出しの外側で新しいランダム(....)を移動するだけです。あなたは100%右です。私は私の答えを編集します。 – BFree

関連する問題