使用相同的种子,每台机器生成的随机数结果是否相同?

18

我目前被卡在了随机生成器上。需求规格说明给出了一个示例,如下所示:

Random rand = new Random(3412);

rand 函数的结果并不直接显示出来,而是用于其他性能中。

我已经按照上面的代码使用种子 3412 来生成随机数。然而,其余性能的结果与示例完全不同。

生成的结果是 518435373,我在在线 C# 编译器上尝试了相同的代码,但得到了不同的生成结果,即 11688046,其余性能的结果也与示例不同。

因此,我想知道在不同的计算机上是否应该有所不同?

顺便说一下,有人能否提供您的计算机上的结果,看看它是否与我的相同。


1
你可以轻松地自行测试。如果相同的随机数出现,你将会得到给定种子的随机数1000次,并且如果你再次运行测试,你将会得到相同的1000个数字。因此,你可以很快地测试并发现这不是事实。 - BugFinder
2
@Bridge:它不是随机的。它是一个伪随机数生成器。 - Jon Skeet
@Bridge:不是的,完全不是。请阅读我回答中引用的文档。 - Jon Skeet
@JonSkeet 我想我误解了 OP 的问题 - 删除了我的原始评论! - Bridge
@BugFinder 我已经测试了几十次,结果都一样,我的意思是第一个生成的随机数与518435373相同。 - Ivan Li
这通常是人们使用时间作为种子,然后调用随机函数的原因,因为它会从不同的位置开始。 - BugFinder
4个回答

18

我期望任何一种实现方法在使用相同的seed(种子)时都会产生相同的随机数序列,但可能涉及不同的实现方法。例如,“在线C#编译器”可能最终使用Mono,我期望它与.NET中的实现有所不同。

我不知道实现方法是否已更改.NET版本之间,但这也是完全可能的。

Random(int) 构造函数的文档说明:

为不同的 Random 对象提供相同的种子值会导致每个实例生成相同的随机数序列。

...但它并未说明不同版本的影响等问题。 哪怕是x86和x64版本是否会产生相同的结果都没有说明。 我期望在任何一个特定的CLR实例中(即一个进程,而不是两个并行运行的CLR),都会得到相同的结果。

如果你需要更加稳定的结果,那么我建议从一个指定的算法开始 - 我打赌Mersenne Twister等算法都有可用的实现。


由于使用的 Visual Studio 版本不同,我正在使用 2010 专业版,但我猜示例代码是使用 2010 Express。这种情况是否可能? - Ivan Li
1
@IvanLi:不,那样做不会有任何区别。但是,针对不同版本的框架可能会有所不同。 - Jon Skeet

9
它没有明确承诺这样做,因此您应该假设它不会这样做。任何规范的一个好原则是不要做出不必要的承诺,以便在以后改进事情时更加自由。实际上,Random的文档说:“Random类的当前实现基于Donald E. Knuth的减法随机数生成器算法。”请注意“当前实现”一词,暗示将来可能会发生变化。这非常强烈地表明,不仅没有承诺在版本之间保持一致性,而且也没有这样的意图。如果规范需要一致的伪随机数,则必须指定算法以及种子值。实际上,即使Random被指定为做出这样的承诺,如果将来需要非.NET实现或部分实现或与其互操作的东西,该怎么办呢?

它确实被指定为在某种程度上做出这样的承诺...只是没有很好地说明:"向不同的随机对象提供相同的种子值会导致每个实例产生相同的随机数序列"。不幸的是,这并没有说明在不同版本之间的稳定性。 - Jon Skeet
@JonSkeet 这就是我所说的唯一承诺。 - Jon Hanna

1

这可能是由于不同的框架版本造成的。请查看this


0
您尝试使用的在线提供程序可能使用了CLR的Mono实现,这与Microsoft提供的实现不同。因此,他们的Random类实现可能有所不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接