我发布了一堆开源的随机数生成器在我的网站上,包括一个正态分布的随机数生成器.为了在10-20范围内生成一个随机整数,我会编写类似于new NormalRandomGenerator(10, 20).Next()
的东西。
有人发表了这样的评论:
只是想知道是否有必要用“double NextDouble()”来实现“int ()”,因为int到双重转换(以及visa-相反)在一些硬件上可能会非常慢,包括最近的PC硬件,尽管我目前还没有特别了解最新的CPU。
我相信这个评论指的是这样一个事实:当有人在我的一个类上调用Next(20)
时,在内部,这个调用转化为类似于(int)someMersenneTwister.NextDouble() * 20
的东西(我不记得我是否使用了舍入)。
我是这样实现的,因为MT既快速又高效(尽管它有一个巨大的随机周期)。据我所知,这是生成随机数的标准方法--调用Next()
,它返回范围[0 .1)然后乘以并键入整数。
我的设计有什么问题吗?有没有更好的方法(更好的性能,更快)来生成一个不使用双数的整数随机数?
抱歉,如果这听起来很含糊。我不确定这里是否有问题。
发布于 2012-03-24 10:00:38
对你的问题没有一个答案(因为它在目前的形式上是没有意义的,海事组织)。但是,看看您的代码,我发现了一些bug和其他问题:
UniformRandomGenerator
时的种子冲突。您从System.Random
继承了这个问题。MersenneTwister.NextDouble
质量低。double
大约有53位数,只有32位。几乎和System.Random
一样糟糕,它填满了31。MersenneTwister.Next(int maxValue)
现在将坏的双倍扩展到所需的间隔上。如果间隔在长,这会导致强烈的偏见。System.Random
有一个非常类似的问题。Next(int minValue, int maxValue)
在计算maxValue-minValue
时包含int溢出。NormalRandomGenerator
的构造函数将平均值计算为this.Mean = ((max - min) / 2) + min;
。这是一个整数除法,因此如果max-min
是奇数,就会导致偏差。奇怪的选择,因为this.Mean
是双倍的。如果您想要生成一致的随机整数,这是我自己的问题的重复:生成具有一定最大值的一致随机整数,它专注于高效地创建这些整数,而不引入偏见。我建议把我的回答和卢凯的回答结合起来。
发布于 2012-03-24 10:27:15
通过缩放一个双倍的范围[0..1]生成随机整数是很好的,只要生成的双值分布足够均匀。然而,大多数伪随机数生成器,包括Mersenne,本机生成(32位无符号)整数,所以如果我们不需要往返双倍,那就太好了。
如果有界N是2的幂,我们可以首先生成一个32位随机整数X并取X,这保证了得到一个均匀分布的结果。但是,如果N不是2的幂,采用模就会在结果分布中产生偏差(例如,有更多的32位无符号整数X 7大于6 )。如果N是小的,检测这样的偏差将需要大量产生的数字,但理论上,分布将是不正确的。
对于非二次方的N,若要生成在[0.N]范围内真正均匀分布的整数,我们可以采用抽样算法:首先计算M,使其最小幂大于N(N= 13,M= 16等)。然后生成一个32位整数X,计算Y=X,如果Y< N,我们就完成了,Y是我们的数字。如果Y >= N,则丢弃它并生成另一个,直到Y
哪种方法最快?只有侧写才能说明。这取决于硬件、语言和代码的质量。
更深入的讨论可以在Knuth的TAOCP第2部分中找到。
发布于 2012-03-24 09:35:58
您可以使用“Random.Next方法”:
http://msdn.microsoft.com/en-us/library/system.random.next.aspx
您将得到一个非负随机数小于指定的最大值,通过您的供应或给出的数字范围(最小和最大)
致以问候。
https://stackoverflow.com/questions/9853817
复制