Why does Random.Next() always return the same number
考虑这种方法:
1 2 3 4 |
在我的机器上,执行这个循环会通过1500次迭代产生相同的数字:
1 2 3 4 5 6 | for (int i = 0; i < 1501; i++) { int random = GenerateRandomNumber(100000000, 999999999); Console.WriteLine(random.ToString()); Console.ReadKey(); } |
每次迭代我都得到145156561。
我没有紧迫的问题,我只是好奇这种行为,因为next(max)说"返回一个小于指定最大值的非负随机数。也许我没有理解一些基本的东西。
您总是用相同的种子播种一个新实例,然后获取第一个最大值。通过使用种子,您可以保证获得相同的结果。
如果您希望有一个静态的、随机的数字生成来产生不同的结果,那么您应该稍微修改一下。然而,由于random不是threadsafe,所以静态使用时需要一些同步。类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private static Random random; private static object syncObj = new object(); private static void InitRandomNumber(int seed) { random = new Random(seed); } private static int GenerateRandomNumber(int max) { lock(syncObj) { if (random == null) random = new Random(); // Or exception... return random.Next(max); } } |
迪尔伯特在2001年也遇到了同样的问题:
http://dilbert.com/strips/comic/2001-10-25/
巧合?
我不这么认为。
Random.org同意:http://www.random.org/analysis/
问题是,您每次都要创建一个具有相同种子数的新随机实例。您应该创建一个单独的随机实例(如有必要,将其存储在静态实例中),并简单地在同一个实例上调用下一个方法。
随机数生成并不是真正随机的,有关更多详细信息,请参阅此维基百科条目。
伪随机数生成器通常通过选择一个种子,然后基于该种子生成一个确定性序列来工作。每次选择相同的种子时,都会生成相同的序列。
.NET中有"only"2^32个不同的随机序列。
不知道内部是如何工作的。在wiki上查一下,但很简单。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
将生成数字1、数字2、数字3、数字4、数字5、数字6(1个种子,1个多数字序列,随机*不是真的,而是大约*)
但是,如果您这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
现在您将得到数字1、数字1、数字1、数字1、数字1(1个种子,6个相等的数字序列,总是从每个相等的序列中选择相同的起始数字)。在某个时刻,数字1会有所不同,因为种子会随着时间的推移而改变。但是你需要等待一段时间,尽管如此,你永远不会从序列中选择数字2。
原因是,每次使用相同的种子生成一个新序列时,序列都是相同的,因此每次随机生成的序列都会选择其序列中的第一个数字,而使用相同的种子,当然总是相同的。
不确定随机生成器的基本方法在技术上是否正确,但这就是它的行为方式。
萨拉姆对所有人,这也让我发疯了。答案很简单。在随机生成之前更改种子。
例子:我想生成1到10之间的随机数
1 2 |
把它放进一个循环里,运行三次。它会给出10以下的随机数。
如果任何人都在寻找"快速而肮脏的"解决方案(我谨慎地使用这个术语),那么这对大多数人来说就足够了。
1 2 3 | int secondsSinceMidnight = Convert.ToInt32(DateTime.Now.Subtract(DateTime.Today).TotalSeconds); Random rand = new Random(secondsSinceMidnight); var usuallyRandomId = rand.Next(); |
请注意我通常使用的是随机的。我同意标记为答案的项目是更正确的方法。