在C#中播种伪随机数生成器

时间:2010-10-30 22:31:25

标签: c# random gethashcode

我需要一个C#的Random类实例的种子,我读到大多数人使用当前时间的滴答计数器。但这是一个64位值,种子需要是32位值。现在我认为返回GetHashCode()的{​​{1}}方法应该为其对象提供合理分布的值,这可以用于避免仅使用滴答计数的低32位。但是,我找不到有关int数据类型的GetHashCode()的任何信息。

所以,我知道这并不重要,但是下面的工作会像我想的那样好(我不能试错法随机性),或者它可能和使用Int64的工作方式相同作为种子?或者甚至可能更糟糕?谁可以对此有所了解。

(int)DateTime.Now.Ticks

编辑:为什么我需要一个种子而不只是让int seed = unchecked(DateTime.Now.Ticks.GetHashCode()); Random r = new Random(seed); 构造函数完成工作?我需要将种子发送给使用相同种子的其他客户端进行相同的随机序列。

3 个答案:

答案 0 :(得分:33)

new Random()已使用当前时间。它相当于new Random(Environment.TickCount)

但这是一个实现细节,可能会在.net

的未来版本中发生变化

我建议使用新的Random(),如果你想获得一个可重现的伪随机值序列,只提供一个固定的种子。

因为你需要一个已知的种子,就像MS一样使用Environment.TickCount。然后将其作为种子传输到其他程序实例。

如果在短间隔(可能是16ms)中创建多个Random实例,则可以将它们播种到相同的值,从而创建相同的伪随机序列。但这很可能不是问题。这种常见的陷阱是由Windows仅每隔几毫秒更新当前时间(DateTime.Now / .UtcNow)和TickCount(Environment.TickCount)引起的。确切的间隔取决于Windows的版本以及正在运行的其他程序。它们不变的典型间隔是16ms或1ms。

答案 1 :(得分:29)

如果您需要使用当前时间以外的其他内容播种(在这种情况下您可以使用默认构造函数),您可以使用:

Random random = new Random(Guid.NewGuid().GetHashCode());

答案 2 :(得分: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++;         

    }