在C#中播种伪随机数生成器
我需要一个C#的Random
类实例的种子,我读到大多数人使用当前时间的ticks计数器。 但这是一个64位值,种子需要是32位值。 现在我认为返回int
的GetHashCode()
方法应该为其对象提供合理分布的值,这可以用于避免仅使用滴答计数的低32位。 但是,我找不到任何关于Int64
数据类型的GetHashCode()的信息。
所以,我知道它并不重要,但是下面的工作会像我想的那样好(我不能试错法随机性),或者它的工作原理与使用(int)DateTime.Now.Ticks
作为种子? 或者甚至可能更糟糕? 谁可以对此有所了解。
int seed = unchecked(DateTime.Now.Ticks.GetHashCode()); Random r = new Random(seed);
编辑:为什么我需要种子而不只是让Random()
构造函数完成工作? 我需要将种子发送给使用相同种子的其他客户端进行相同的随机序列。
new Random()
已经使用了当前时间。 它相当于new Random(Environment.TickCount)
。
但这是一个实现细节,可能会在.net的未来版本中发生变化
我建议使用新的Random(),如果你想获得一个可重现的伪随机值序列,只提供一个固定的种子。
既然你需要一个已知的种子,就像MS一样使用Environment.TickCount
。 然后将其作为种子传输到其他程序实例。
如果在短时间间隔内创建多个Random
实例(可能是16ms),则可以将它们播种到相同的值,从而创建相同的伪随机序列。 但这很可能不是问题。 这种常见的缺陷是由Windows仅每隔几毫秒更新当前时间( DateTime.Now
/ .UtcNow
)和.UtcNow
( Environment.TickCount
)引起的。 确切的时间间隔取决于Windows的版本以及正在运行的其他程序。 它们不变的典型间隔是16ms或1ms。
如果你需要用当前时间以外的东西来种子(在这种情况下你可以使用默认的构造函数),你可以使用:
Random random = new Random(Guid.NewGuid().GetHashCode());
我有一个类似的问题,从更大的问题列表中选择一组随机的问题。 但是当我使用时间作为种子时,它会给出相同的随机数。
所以这是我的解决方案。
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("
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++; }