16

C# のRandomクラスのインスタンスのシードが必要ですが、ほとんどの人が現在の時間のティック カウンターを使用していると読みました。ただし、これは 64 ビット値であり、シードは 32 ビット値である必要があります。GetHashCode()を返すメソッドは、intそのオブジェクトに適切に分散された値を提供する必要があり、これを使用して、ティック カウントの下位 32 ビットのみを使用することを避けることができると考えました。Int64ただし、データ型の GetHashCode() については何も見つかりませんでした。

だから、それはあまり重要ではないことはわかっていますが、次のことは私が思うほどうまくいくでしょうか(ランダム性を試行錯誤することはできません)、それとも(int)DateTime.Now.Ticksシードとして使用するのと同じように機能するのでしょうか? それとも、それはさらに悪いことですか?誰がこれに光を当てることができますか。

int seed = unchecked(DateTime.Now.Ticks.GetHashCode());
Random r = new Random(seed);

編集:なぜシードが必要なのに、Random()コンストラクターに仕事をさせないのですか? 同じランダム シーケンスに同じシードを使用する他のクライアントにシードを送信する必要があります。

4

3 に答える 3

34

new Random()はすでに現在の時刻を使用しています。と同等new Random(Environment.TickCount)です。

ただし、これは実装の詳細であり、.net の将来のバージョンで変更される可能性があります

new Random() を使用することをお勧めします。疑似ランダム値の再現可能なシーケンスを取得したい場合は、固定シードのみを提供してください。

既知のシードが必要なので、Environment.TickCountMS と同じように使用してください。そして、それをシードとして他のプログラム インスタンスに送信します。

の複数のインスタンスをRandom短い間隔 (16 ミリ秒の可能性があります) で作成すると、それらは同じ値にシードされるため、同じ疑似ランダム シーケンスが作成されます。しかし、それはおそらくここでは問題ではありません。この一般的な落とし穴は、ウィンドウが現在の時刻 ( DateTime.Now/ .UtcNow) と TickCount( Environment.TickCount) を数ミリ秒ごとに更新することによって発生します。正確な間隔は、Windows のバージョンと実行中の他のプログラムによって異なります。変化しない典型的な間隔は 16ms または 1ms です。

于 2010-10-30T22:33:25.983 に答える
31

現在の時刻以外でシードする必要がある場合(その場合、デフォルトのコンストラクターを使用できます)、これを使用できます。

Random random = new Random(Guid.NewGuid().GetHashCode());
于 2010-10-30T22:38:52.273 に答える
0

より大きな質問リストからランダムな一連の質問を選択するために、同様の質問がありました。しかし、時間をシードとして使用すると、同じ乱数が得られます。

だからここに私の解決策があります。

    int TOTALQ = 7;
    int NOOFQ = 5;

    int[] selectedQuestion = new int[TOTALQ];

    int[] askQuestion = new int[NOOFQ];

    /*   Genarae a random number 1 to TOTALQ
     *   - if that number in selectedQuestion array is not o
     *   -     Fill askQuestion array with that number
     *   -     remove that number from selectedQuestion
     *   - if not re-do that - - while - array is not full.    
     */

    for (int i = 0; i < TOTALQ; i++)  // fill the array
        selectedQuestion[i] = 1;

    int question = 0;

    int seed = 1;

    while (question < NOOFQ)
    {       
        DateTime now1 = new DateTime();
        now1 = DateTime.Now;    
        Random rand = new Random(seed+now1.Millisecond);
         int RandomQuestion = rand.Next(1, TOTALQ);

         Response.Write("<br/> seed  " + seed + " Random number " + RandomQuestion );



        if (selectedQuestion[RandomQuestion] != 0)      
        {
            selectedQuestion[RandomQuestion] = 0;  // set that q =0 so not to select           
            askQuestion[question] = selectedQuestion[RandomQuestion];
            Response.Write(".  Question no " + question + " will be question " + RandomQuestion + " from list " );
            question++;
        }

        seed++;         

    }
于 2014-09-19T08:21:32.417 に答える