根据本文档 https://developer.apple.com/library/mac/documentation/darwin/reference/manpages/man3/arc4random.3.html,
arc4random_uniform()
推荐使用类似的结构arc4random() % upper_bound
因为当上限不是 2 的幂时,它可以避免“模偏差”。
偏见有多严重?例如,如果我生成上限为 6 的随机数,那么使用arc4random
with %
and arc4random_uniform()
?
arc4random() 返回一个无符号 32 位整数,这意味着值介于
0 和 2^32-1 = 4 294 967 295。
现在,偏差是由以下事实造成的:使用以下命令创建的多个子区间
模数不完全适合随机输出范围。
为了清楚起见,让我们想象一个随机生成器,它创建 0 到 198 之间的数字
包括的。您想要 0 到 99 之间的数字,因此您计算 random() % 100,
产生 0 到 99:
0 % 100 = 0
99% 100 = 99
100% 100 = 0
198% 100 = 98
你看99是唯一一个只能出现的数字once虽然所有
其他可能发生twice在跑步中。这意味着 99 的概率
正好减半,这也是偏差中最坏的情况,其中至少
涉及2个子区间。
由于小于范围间隔的所有二的幂都很好地适合
2^32 间隔,在这种情况下偏差消失。
这意味着模数结果集越小且越高
随机输出范围越大,偏差越小。在你的例子中,6是你的上限
界(我假设 0 是下界),所以你使用 % 7,结果是 0-3
出现 613 566 757 次,而 4-6 出现 613 566 756 次。
所以 0-3 的可能性是 613 566 757 / 613 566 756 = 1.0000000016298 倍
比4-6。
虽然这似乎很容易被忽视,但一些实验(尤其是蒙特卡洛实验)
实验)之所以有缺陷,正是因为这些看似令人难以置信的小
差异非常重要。
如果所需的输出范围是,更糟糕的是偏差bigger比
随机目标范围。请阅读费舍尔-耶茨洗牌 https://en.wikipedia.org/wiki/Fisher-Yates_shuffle入口
因为许多扑克网站都经历过惨痛的教训才知道正常的线性
同余的随机生成器和糟糕的洗牌算法导致
不可能的或非常可能的牌组或更糟的牌组,可预测 decks.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)