16

我需要一个 C#Random类实例的种子,并且我读到大多数人为此使用当前时间的滴答计数器。但这是一个 64 位的值,种子需要是一个 32 位的值。现在我认为GetHashCode()返回 an 的方法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.TickCount所以就像 MS 一样使用。然后将其作为种子传输给其他程序实例。

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

于 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 回答