我总是通过丢弃偏差范围内的任何数字来生成无偏的随机数。与此相似
int biasCount = MAX_INT % max
int maxSafeNumber = MAX_INT - biasCount;
int generatedNumber = 0;
do
{
generatedNumber = GenerateNumber();
} while (generatedNumber > maxSafeNumber)
return generatedNumber % max;
今天,一位朋友向我展示了他如何通过将生成的数字转换为浮点数然后将其与最大值相乘来生成随机数。
float percent = generatedNumber / (float)MAX_INT;
return (int)(percent * max);
这似乎通过不必首先使用模数来解决偏差问题。它看起来也很简单快速。 有没有理由说浮动方法不像第一个那样安全(无偏见)?
答案 0 :(得分:4)
带有地板的浮动方法(即你的演员)引入了偏见 反对您范围内的最大值。
要返回max
,generatedNumber == MAX_INT
必须为真。
因此,max
的概率为1/MAX_INT
,而其他数字则为max/MAX_INT
范围有概率MAX_INT
max
还存在别名问题
不是max
的倍数。这使得范围内的一些值更多
可能比其他人。 MAX_INT
和{{1}}之间的差异越大,此偏差越小。(假设你得到并希望统一分发。)
来自GoingNative 2013的Stephan T. Lavavej的演讲通过随机数来解决许多常见的谬误,包括这些范围方案。它在实现中以C ++为中心,但所有概念都延续到任何语言: http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful
答案 1 :(得分:1)
即使输入数均匀分布,float方法也可能无法生成均匀分布的输出数。要查看它发生故障的地方,请使用小数字来举例说明max = 6,MAX_INT = 8
当MAX_INT很大时会变得更好,但它几乎不会完美。