使用C#的随机数

Lia*_*amB 11 c# random

我正在寻找生成1到5百万之间的随机数.这个过程不一定要快(虽然它会很好),但它必须尽可能随机(我知道什么都不是随机的).我有种子的各种数据源.

我不确定.NET Random类是否足够好.

这将用于选择中奖彩票.

Chr*_*isF 17

System.Random堂课可能还不错:

从有限的数字集合中以相等的概率选择伪随机数.所选择的数字不是完全随机的,因为使用确定的数学算法来选择它们,但是出于实际目的它们是足够随机的.Random类的当前实现基于Donald E. Knuth的减法随机数生成器算法.有关更多信息,请参阅DE Knuth."计算机编程的艺术,第2卷:半数值算法".Addison-Wesley,Reading,MA,第二版,1981.

您唯一需要注意的是,您不要经常重复使用相同的种子:

如果重复使用相同的种子,则生成相同的数字序列.产生不同序列的一种方法是使种子值与时间相关,从而与每个新的Random实例产生不同的序列.


Ste*_*ven 7

如果需要加密随机数,请使用System.Security.Cryptography.RNGCryptoServiceProvider该类或使用RandomNumberGenerator.Create()工厂方法创建默认配置的随机数生成器.

  • RNGCryptServiceProvider适用于填充字节数组,因此您需要转换回int并检查它是否在正确的范围内 (3认同)

Met*_*urf 5

请参阅Jon Skeet的博客文章Revisiting Randomness,对如何使用Randomness进行了非常好的评论:

重新审视随机性
几乎每个包含"随机"和"重复"字样的Stack Overflow问题都有相同的基本答案.它是.NET,Java中最常见的"陷阱"之一,毫无疑问是其他平台:创建一个新的随机数生成器而不指定种子将取决于当前的时刻.与您创建和使用随机数生成器的频率相比,计算机测量的当前时间不会经常变化 - 因此重复创建Random的新实例并使用它一次的代码最终将显示出大量重复.

更多...


Aar*_*ght 5

实际上我最近在不同类型的PRNG上阅读了一篇非常好的文章,以及它们在几种不同的随机性测试方面的表现.不幸的是,我现在似乎无法找到它.然而,它的要点是,几乎所有流行编程语言中的默认随机数生成器都非常天真,并且具有相当大的偏差.

另一个答案已经提到,无论算法多么复杂,对于加密应用程序来说,根本没有PRNG.这是真的.既然你提到这将用于"选择一张中奖票",那么我们暂时忽略它.

.NET System.Random类使用的Knuth算法主要针对速度而非随机分布进行优化.对于许多目的而言,它是"随机的",大多数应用程序从不偏离太远,但在(a)游戏和(b)统计模拟领域,大多数人似乎认为这是一个糟糕的选择.它比以前在旧库中默认的LCG更好,但你仍然不想将它用于乐透之类的东西.

不要误以为你只是使用加密源.与加密的RNG的问题是,他们填写的字节流,但是把这个变成之间的一个随机整数XŸ要求你做一些模运算(或倒圆-相同的结果,无论哪种方式).如果你的随机范围没有完全均匀地划分为由字节长度定义的2的幂,那么你将最终得到较低数字的偏差.生成的数据具有高熵,但您的结果会有偏差.

举一个简单的例子,让我们说你从1到10得到一个"完美"的随机数,现在你想把它变成1到7之间的随机数.你怎么做?简单计算result % 7将严重偏向数字1-3.在使用加密RNG时,有一些方法可以减少偏差,但我想说的是加密RNG是专为加密应用而设计的,而使用其中一个用于蒙特卡罗模拟通常不是最好的想法.

据我所知,目前在游戏应用中常用的最受欢迎的"好"PRNG是Mersenne Twister.这里有一个.NET实现.该算法通过所有Diehard测试进行随机分布; 当您使用随机数进行概率和统计应用时,它几乎没有偏差,是一个不错的选择.

GNU科学图书馆也有许多RNG算法,毫不奇怪,Mersenne Twister位于列表的首位.不过,有些其他人值得关注好奇心.RANLUX在死硬测试IIRC上也得分很高.

当然,埃里克对他的评论是正确的; 如果您对随机数字的"随机性"没有具体的技术要求,那么所有这些信息都是徒劳的.我使用的定义适用于影响力相对较小的赌博/博彩应用程序(即不是每天有数百万访问者的主要注册赌博网站 - 对于那些随机性有更严格的规则).