Random number generator generating same numbers each time application is ran
我知道这个问题有好几次被提出来,但这些解决方案都不适合我。
首先,我在名为
1 2 3 4 5 |
这总是给我相同的号码,然后在看了这个答案之后,我做了如下的事情:
1 2 3 4 5 |
这给了我下面的数字
1 2 3 4 5 | 325467165 506683626 1623525913 2344573 1485571032 |
现在,虽然这对于循环的每次迭代都是好的,但这里的问题是,当我停止并重新运行应用程序时,我会得到与以前相同的数字。
1 2 3 4 5 | 325467165 506683626 1623525913 2344573 1485571032 |
这种行为是只在调试期间发生的,还是每次调用
您在这里使用相同的种子1000来播种
1 |
由于当前时间用作种子,因此不会执行此操作:
1 |
看看采用
Providing an identical seed value to different Random objects causes
each instance to produce identical sequences of random numbers.
按MSDN计算。
1 2 3 | public Random( int Seed ) |
Seed
A number used to calculate a starting value for the pseudo-random number sequence. If a negative number is specified, the absolute value of the number is used.
大多数初学者犯的涉及RNG(随机数生成器)的错误的原因是缺乏对"种子"是什么和它做什么的理解。
那么什么是"种子"?在
325467165
506683626
1623525913
2344573
1485571032
在第一个代码中,每次需要一个随机数时,都会用相同的种子创建一个新的伪随机数序列,因此很明显,数组中填充了相同的数字:
这也解释了为什么每次启动应用程序时,第二个代码总是生成相同的伪随机数序列。
为了确保应用程序总是生成不同的伪随机序列,每次都需要使用不同的种子。到目前为止,确保这一点的最简单方法是慢慢来,字面上。
1 2 | Random rnd = new Random(DateTime.UtcNow.Millisecond); // Taking the millisecond component, because it changes quickly |
幸运的是,您不必键入这么多,因为
1 |
请记住,
另一件需要注意的事情是,创建多个
1 2 3 4 |
在上面的代码中,
这怎么可能?好吧,(联合国)幸运的是,CPU正在飞速发展。一个1GHz的CPU每秒可以执行大约10亿条指令(给出或接受);这是每1纳秒1条指令,或者每一百万分之一秒1条指令。创建一个新的
因为它对于保持多个终端的同步非常有用。
想象一个游戏,其中重要的现象随机出现,如天气变化,可能完全颠覆游戏。你不会只想让一方遭受雾害,而其他方仍然从晴朗的天气中获利,对吧?
当然,您可以让服务器或主机生成随机的天气变化并通知玩家;或者您可以在游戏开始前定义种子,并使用该种子来确保整个游戏中所有玩家的"随机性"。
编码不是很有趣吗?
您需要更改:
1 |
到
1 |
从随机构造函数文档中:
The default seed value is derived from the system clock and has finite
resolution. As a result, different Random objects that are created in
close succession by a call to the default constructor will have
identical default seed values and, therefore, will produce identical
sets of random numbers. This problem can be avoided by using a single
Random object to generate all random numbers. You can also work around
it by modifying the seed value returned by the system clock and then
explicitly providing this new seed value to the Random(Int32)
constructor. For more information, see the Random(Int32) constructor.
关键概念是随机种子——随机种子从中衍生出其他一切的初始数据。如果种子是相同的,那么"随机"序列将是相同的。
默认情况下,seed设置为零,这显然会导致程序运行之间的重复序列。
为了避免这种情况,您可以这样构造您的随机对象:
1 |
…引擎盖下面是:
1 |
这将从操作系统启动开始以毫秒数初始化随机对象。每次程序启动时,这都会有所不同,因此每次都会得到不同的随机序列。
random.next()方法生成伪随机数。您应该声明并初始化一个随机对象,而不是每次创建一个新对象。也不需要使用任何晶体造影术。:)
你应该使用类级随机变量。如果在方法级别使用一个新的随机数作为局部变量,则时间相关的种子将重复自身,生成相同的随机数序列。
1 2 3 4 5 6 7 8 | class Program { static Random _r = new Random(); static void Main() { // use _r variable to generate random number } } |