2

我总是通过丢弃有偏范围内的任何数字来生成无偏随机数。与此类似

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);

这似乎通过首先不必使用模数来解决偏差问题。它看起来也简单快速。浮动方法不像第一个方法那样安全(无偏见)有什么原因吗?

4

2 回答 2

4
  • 带有地板的浮动方法(即您的演员表)引入了对您范围内最大值的偏差。

    为了返回maxgeneratedNumber == MAX_INT必须为真。max概率也是如此1/MAX_INT,而范围内的每个其他数字都有概率max/MAX_INT

  • 正如亨利指出的那样,如果MAX_INT 不是max. 这使得该范围内的某些值比其他值更有可能。之间的差异越大,max这种MAX_INT偏差就越小。

(假设你得到并且想要一个统一的分布。)

来自 GoingNative 2013 的 Stephan T. Lavavej 的这个演讲讨论了许多关于随机数的常见谬误,包括这些范围方案。它在实现中以 C++ 为中心,但所有概念都适用于任何语言: http ://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

于 2013-10-28T08:35:08.107 回答
1

即使输入数是均匀分布的,float 方法也可能不会生成均匀分布的输出数。要查看它在哪里发生故障,请做一些小数字示例,例如 max = 6, MAX_INT = 8

当 MAX_INT 很大时它会变得更好,但它几乎从来都不是完美的。

于 2013-10-28T08:42:53.227 回答