【问题标题】:Will this function return uniformly distributed random values?这个函数会返回均匀分布的随机值吗?
【发布时间】:2014-04-19 02:05:04
【问题描述】:

我想返回一个范围内的统一随机值。范围的大小和最小值是预先计算的。

我正在使用广岛大学团队分发的双精度 Mersenne Twister 的参考实现。我目前正在使用dsfmt_genrand_close_open() 函数,其描述如下:

"生成并返回一个在[0, 1)范围内均匀分布的双精度伪随机数"

这是函数:

uint64_t gen_addr_in_range (uint64_t range, uint64_t low_addr) {
    return (dsfmt_genrand_close_open(&dsfmt) * (range + 1)) + low_addr;
}

这个函数的输出在给定范围内是否一致?

【问题讨论】:

  • 作为一个非数学家,我相信如果dsfmt_genrand_close_open[0,1)之间是一致的,那么如果你将它乘以一个常数乘数(范围+1)那么你应该得到同样随机的分布。不相关的一点:如果你得到一个范围内的随机地址(似乎有效),你为什么要使用 uint64_t 来存储地址?不应该是void *吗?
  • 这些地址是内存模拟中的数据

标签: c random statistics probability mersenne-twister


【解决方案1】:

作为非数学家:

连续均匀分布具有以下形式(以编程方式):

if (a <= x <= b)
    f(x) = 1/(b-a)
else
    f(x) = 0

将此分布乘以常数 A 将得到:

if (A*a <= x <= A*b)
    f(x) = 1/(A*b-A*a)
else
    f(x) = 0

这是另一种均匀分布。

同样,按常数 c 缩放会产生:

if ((a+c) <= x <= (b+c))
    f(x) = 1/((b+c)-(a+c))
else
    f(x) = 0

这又是一个均匀分布。

我觉得你很好。

【讨论】:

    【解决方案2】:

    要考虑的替代方案(假设 range 限制为 32 位)是这样的

    return( low_addr + arc4random_uniform( range ) );
    

    生成从low_addrlow_addr + range - 1 的均匀分布值。

    【讨论】:

    • 双精度数的尾数为 53 位,因此它比“正常杀伤”要少,而不是“过度杀伤”
    • @OregonTrail 太好了,先生。我没有考虑他使用 64 位数字,arc4random_uniform 不支持,除非 range 参数限制为 32 位。事实上,您已经回答了他最初的问题,因为他提出的 rand 函数无法在整个 64 位范围内生成均匀分布,因为它只有 53 位可供使用。
    猜你喜欢
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2021-12-28
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多