[英]When getting rid of modulo bias how does min = -upper_bound % upper_bound; // work?
在回答这个问题时 ,提供了以下解决方案,简洁的OpenBSD,为简洁起见,
uint32_t foo( uint32_t limit ) {
uint32_t min = -limit % limit, r = 0;
for(;;) {
r = random_function();
if ( r >= min ) break;
}
return r % limit;
}
线路uint32_t min = -limit % limit
确切工作原理是什么? 我想知道的是,是否有一个数学证明它确实计算了随机数的一些下限并充分消除了模偏差?
在-limit % limit
,考虑-limit
产生的值是2 w - limit
,其中w是所使用的无符号类型的位宽度,因为无符号算术被定义为包装模2 w 。 (假设limit
的类型不比int
窄,这将导致它被提升为int
并且使用了带符号的算术,并且代码可能会中断。)然后认识到2 w - limit
与2 w模数limit
是一致的。 因此,当2 w除以limit
时, limit
-limit % limit
产生余数。 让这是min
。
在整数集合{0,1,2,3,...2 瓦特 -1},与余数r(0≤[R <若干limit
时除以) limit
至少出现地板(2 W / limit
)次。 我们可以找出它们中的每:对于0≤q <地板(2 W / limit
)中,q• limit
+ r的余数r,并在该组。 如果0≤[R < min
,然后还有一个这样的号码在该组,其中q =地板(2 W / limit
)。 那些占了集{0,1,2,3,... 2 w -1}中的所有数字,因为floor(2 w / limit
)• limit
+ min
= 2 w ,所以我们的计数完成了。 对于r个不同的余数,有一个(2 w / limit
)+1个数字,其中剩余部分在集合中,而对于min
- r其他剩余部分,有一个余量(2 w / limit
),其余部分在集合中。
现在假设我们从这个集合{0,1,2,3,... 2 w -1}中随机地随机绘制一个数字。 与余数0≤[R清楚号码< min
可能因为有在该组以上并略微更经常地出现,。 通过拒绝每个这样的数字的一个实例,我们将它们从我们的分发中排除。 实际上,我们从集合{ min
, min
+ 1, min
+ 2,... 2 w -1}中抽取。 结果是具有特定余数的每个数字的确切下限(2 w / limit
)的分布。
由于每个余数在有效分布中表示相等的次数,因此每个余数具有通过均匀抽取选择的相等机会。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.