我发布了一堆开源随机数生成器on my site,包括一个正态分布的随机数生成器。要生成10-20范围内的随机整数,我会写一些类似new NormalRandomGenerator(10, 20).Next()
的内容。
有人发表了这条评论:
只是想知道是否有必要实现“int Next()” 术语“double NextDouble()”,作为双重转换的int(和 反之亦然)在某些硬件上可能会非常慢,包括最近的PC 硬件,虽然我不是特别关注最新的CPU 此刻。
我相信这条评论指的是当有人在我的某个课程内部调用Next(20)
时,该调用转换为类似(int)someMersenneTwister.NextDouble() * 20
的内容(我不记得是否使用了舍入)
我是这样实现的,因为MT既快速又高效(尽管它有很长的随机期)。根据我的理解,这是生成随机数的标准方法 - 调用Next()
,返回[0 .. 1]范围内的double,然后乘以和类型转换为int。
我的设计方面有问题吗?是否有更好的方法(更高性能,更快)生成不使用双精度的整数随机数?
对不起,如果这听起来很模糊。我不确定这里是否有问题。
答案 0 :(得分:3)
不是你的问题的答案(因为它目前的形式IMO没有意义)。但是查看代码我发现了许多错误和其他问题:
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
是双重的。如果你想生成统一的随机整数,那就是我自己的问题的重复:Generating uniform random integers with a certain maximum,它专注于在不引入偏见的情况下有效地创建这些整数。我建议将我的答案与LukeH的答案结合起来。
答案 1 :(得分:0)
通过缩放范围[0..1]中的double来生成随机整数很好,只要生成的double足够均匀分布即可。但是,大多数伪随机数生成器(包括Mersenne Twister)本身生成(32位无符号)整数,因此如果我们不需要使往返加倍就会很好。
如果绑定N是2的幂,我们可以先生成一个32位随机整数X并取X mod N.这可以保证产生均匀分布的结果。但是如果N不是2的幂,则采用模数会在得到的分布中产生偏差(例如,有更多的32位无符号整数,其中X mod 7为0而不是6。)如果N很小,则检测到这样的偏见需要大量生成的数字,但理论上,分布不正确。
为了生成N范围内真正均匀分布的整数,对于不是2的幂的N,我们可以求助于采样算法:首先计算M使得它是2的最小幂,大于2 N(N = 13,M = 16,依此类推)。然后生成32位整数X,计算Y = X mod M.现在,如果Y
哪种方法最快?只有剖析才能说明问题。这取决于硬件,语言和代码质量。
在Knuth的TAOCP第2部分中可以找到更全面的讨论。
答案 2 :(得分:-1)
您可以使用'Random.Next Method':
http://msdn.microsoft.com/en-us/library/system.random.next.aspx
您将获得一个小于指定最大值的非负随机数,或者给出一个数字范围(最小值和最大值)
问候。