Random.Next会停止随机吗?

5

我需要创建0到2之间的随机数,因此我正在使用以下代码:

//field level
private static Random _random = new Random();

//used in a method
_random.Next(0, 2)

我的问题是:随机数序列是否会重复或停止?我需要每天重新创建(_random = new Random();)吗?

6
是的,这个序列最终会重复,因为它并不是真正的随机。 - Gabe
1
哲学问题:任何事情都是真正的随机还是蝴蝶效应的结果? ;) - Mayank
@Gabe 如果这个周期等于我们宇宙的持续时间,那么它是随机的还是非随机的?在某个点上,某些事情已经足够随机了。你已经做出了一个p => q,但是p(实际上并不随机)不需要“指向”q,或者你可以认为我们的宇宙是“不随机的”...好吧...我们讨论得太深奥了... :-) - xanatos
如果速度和安全性不是问题,System.Math.Random就可以了。如果你想要更不可预测的数字,考虑使用类似CSPRandomNumberGenerator这样的东西(http://msdn.microsoft.com/en-au/library/system.security.cryptography.rngcryptoserviceprovider.aspx)。 - akton
7个回答

7

你的代码已经很好了。

你不需要每天创建一个新的 Random 对象。

请注意,Random 并不是真正的随机数生成器,而是产生伪随机结果。


3
实际上,如果在一秒钟内生成一个新的Random对象,并且之前已经生成了一个Random对象,那么将生成相同的Random对象,并且您将继续获得相同的值。 - Armen Tsirunyan

4

如果您查看文档中的备注部分,您会发现System.Random是一个伪随机生成器。

这意味着理论上序列最终会重复。实际上,这很大程度上取决于您所做的事情。例如,序列的长度足以使任何人都不会注意到它们正在重复。另一方面,它对于加密来说几乎没有用处。

编辑添加:每天重新启动不会有太大区别。要么伪随机性对您足够,要么您需要研究一种安全的方式来生成随机数。


2

Math.Random 返回一个32位有符号整数,如果你不重新播种,它将在第2^32个调用时重复。如果你重新播种,它将更快地重复。


1
我不相信这是真的:在达到2^32值之前,你可能会得到重复的值,但是该序列的长度要显著长于此。 - mavnn
他们使用线性同余发生器(LCG)。关于LCG,请参见此处:http://en.wikipedia.org/wiki/Linear_congruential_generator。 - Bernd Elkemann
我的错。我记错了,他们使用的是梅森旋转算法,但似乎我想到的是Python。 - mavnn
你为什么认为他们使用LCG?根据https://dev59.com/z1TTa4cB1Zd3GeqPuqwV#5117777,他们使用的是具有更长周期的LFG。 - Gabe

2

2
如果您阅读此文,您将看到Random(目前)基于(24,55)的减法滞后斐波那契生成器,这应该保证周期至少为2^55。但是,如果您查看页面末尾,有人指出可能存在一个错误(2010年10月ytosa的评论)。

http://msdn.microsoft.com/en-us/library/system.random(v=vs.100).aspx

假设除非您需要进行“特殊”应用程序,否则周期足够长! 我要补充的是,维基http://en.wikipedia.org/wiki/Lagged_Fibonacci_generator告诉我们,有一篇论文表明滞后斐波那契数列的24,55序列不够“随机”(在 LFG问题下)。

参考链接没有显示任何评论。ytosa的这个错误报告应该足够清楚地解释了问题:http://connect.microsoft.com/VisualStudio/feedback/details/634761/system-random-serious-bug - Levitikon
@Levitikon 你需要选择版本4.0...作者是ytosa而不是tosa...所以现在正确的链接是http://msdn.microsoft.com/en-us/library/system.random(v=vs.100).aspx - xanatos

0
值得一提(至少根据我的经验),如果您在声明时有一个方法
 Random myRand=new Random();
 myRand.Next(10);  
 //...doing somthing with that

然后,如果您在循环中多次调用此方法,可能会得到许多重复的结果(这就是我的情况)。

我找到的解决方案是将Random myRand=new Random()移动到成为成员初始化语句(而不是方法的局部变量),与您所做的匹配。

之后,就不再有重复的结果了。


0
如果目的是生成加密安全的随机数,那么你应该使用更好的 PRNG。如果你只是想要偶尔的随机数,并且真正的随机性并不关键(我想这是因为输出值的范围),那么你的代码很可能已经足够了。

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