在给定范围内生成均匀随机偏差
我想在给定范围内生成均匀分布的随机整数。我正在使用的解释语言有一个内置快速随机数生成器,它返回范围为0(包含)到1(包含)范围内的浮点数。不幸的是,这意味着我不能使用standard solution seen in another SO question(当RNG之间返回0(包括数字)到1(不包括)),用于在给定的范围内产生均匀分布的随机整数:在给定范围内生成均匀随机偏差
result=Int((highest - lowest + 1) * RNG() + lowest)
唯一明智的方法目前我可以看到,在罕见的情况下,随机数发生器返回1以请求新的号码。
但是如果有人知道更好的方法,我很乐意听到它。
罗布
注意:将现有的随机数发生器,以这种语言会导致infeasibly缓慢,恐怕这不是一个可行的解决方案的东西。
编辑:链接到实际的答案。
想必你对速度非常感兴趣,否则你只会在每次RNG呼叫时吸食有条件的测试。任何其他的选择可能会比分支慢...
...除非你确切知道RNG的内部结构是什么。特别是,它的返回值是什么?如果它们不是IEEE-754浮标或双打,那么我有同感。如果是这样,它们中有多少个真实的随机性?你会期望24浮动和53双打(尾数位数)。如果这些是天真地生成的,你可能可以使用轮班和掩码将一个简单的旧随机整数生成器一起破解掉,然后在你的函数中使用它(取决于你的范围的大小,你可以使用如果你有这样的发电机,更多的班次和口罩可以避免任何分支)。如果你有一个高质量的发生器产生全质量的24位或53位随机数,那么你可以用一个乘法将它们从[0,1]转换为[0,1]:乘以最大的可生成的浮点数点数小于1,并且你的范围问题消失了。如果mantissas没有完全填充随机位,这个技巧仍然可以工作,但是你需要做更多的工作来找到合适的乘法器。
你可能想看看C source to the Mersenne Twister看到他们对类似问题的处理。
我不明白为什么需要+ 1
。如果随机数发生器产生在[0,1]区间则值的均匀分布...
result = lowest + (rng() * (highest - lowest))
应该给你值的最低
之间rng() == 0, result = lowest + 0 = lowest
和unform分布最高
rng() == 1, result = lowest + highest - lowest = highest
包含+ 1指该上限将所生成的数量可以高于最高
rng() == 1, result = lowest + highest - lowest + 1 = highest + 1
。
由此产生的值分布将与随机数的分布相同,因此均匀性取决于随机数生成器的质量。
从您的评论下面,你是正确的指出,Int()将成为拖尾分布在尾部的来源。最好使用Round()到最近的整数或任何你在脚本语言中的等价物。
这是不正确的,例如最低= 0和最高= 9。当RNG = 1时只输出9,但当RNG的输出介于0和0.1之间时输出0 – RobS 2009-01-15 09:55:36
你还没有解释为什么上述解决方案不起作用。如果随机数发生器是一个很好的随机数的近似值,那么它的结果分布应该是一致的,计算结果也是一样的。 – Simon 2009-01-15 09:39:49
因为RNG的范围是0(包括)到1(包括),所以我们可能以结果=最高+ 1(即在期望范围外)结束 – RobS 2009-01-15 09:54:59