- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
模偏差是天真地使用模运算来获得小于给定“上限”的伪随机数时出现的问题。
因此,作为一名 C 程序员,我正在使用 arc4random_uniform()
函数的修改版本来生成均匀分布的伪随机数。
问题是我不明白这个函数在数学上是如何工作的。
这是函数的解释性注释,后面是完整源代码的链接:
/*
* Calculate a uniformly distributed random number less than upper_bound
* avoiding "modulo bias".
*
* Uniformity is achieved by generating new random numbers until the one
* returned is outside the range [0, 2**32 % upper_bound). This
* guarantees the selected random number will be inside
* [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
* after reduction modulo upper_bound.
*/
从上面的注释我们可以定义:
[2^32 % upper_bound, 2^32)
- 区间 A[0, upper_bound)
- 区间 B为了工作,该函数依赖于区间 A 映射到区间 B 的事实。
我的问题是:从数学上讲,区间 A 中的数字如何一致地映射到区间 B 中的数字?有这方面的证据吗?
最佳答案
有时,从一个易于理解的示例开始,然后从那里进行概括会有所帮助。为了简单起见,我们假设 arc4random
返回一个 uint8_t
而不是 uint32_t
,所以 arc4random
的输出是区间 [0,256)
中的一个数字。让我们选择 7 的 upper_bound
。
注意7不能整除256
256 = 7 * 36 + 4
这意味着天真地使用取模运算得到小于 7 的伪随机数将导致以下概率分布
37/256 for outcomes 0,1,2,3
36/256 for outcomes 4,5,6
这就是所谓的模偏差,结果 0、1、2、3 比结果 4、5、6 更有可能。
为避免模偏差,我们可以简单地拒绝值 252,253,254,255,并生成一个新数字,直到结果位于区间 [0,252)
内。区间 [0,252)
中的所有数字都具有相同的概率(拒绝较高数字不会影响较低数字的分配)。又因为7整除252,所以得到的概率分布是均匀的
36/252 for outcomes 0,1,2,3,4,5,6,7
这基本上就是 arc4random_uniform
所做的,除了 arc4random_uniform
拒绝范围底部的数字。具体来说,间隔 A 将是
[2^8 % 7, 2^8) which is [4, 256)
在区间 [4,256) 中生成一个数字(称其为 N
)后,最终计算为
outcome = N % 7
区间 [4,256) 中有 252 个数字,由于 252 是 7 的倍数,因此区间 [0,7) 中的每个结果都有相等的概率。
这就是 arc4random_uniform 的工作原理,它拒绝/重试小范围的数字,剩余范围内的数字计数是 upper_bound 的倍数。 (由于 upper_bound 与 2^32 相比通常是一个较小的数字,因此对单个结果进行多次重试的几率非常小。)
但你真的关心模偏差吗?在大多数情况下,答案是“否”。考虑我们的上限为 7 的示例。朴素模实现的概率分布是
613566757 / 4294967296 for outcomes 0,1,2,3
613566756 / 4294967296 for outcomes 4,5,6
这是小于 0.0000002% 的模偏差。
因此,您可以选择:要么在重试上花费极少的时间以获得完美的分布,要么接受概率分布中的极小误差以避免重试。
关于c - 消除模偏差 : how is it achieved in the arc4random_uniform() function?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32258979/
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How do short URLs services work? 我经常看到来自 bitly.com 的缩短
我编写了一个简单的游戏,并希望将 GameCenter Achievements 与其集成。 我想尝试以一种干净整洁的方式来做到这一点,这样很容易添加额外的成就。 在我看来,成就包含以下内容: 触发器
我在 Dribble 中发现了一些 Appbar 设计 https://dribbble.com/shots/9175650-Beauty-Salon-App/attachments/1218583?
我有这样的东西。 function a() { ajax(callback_function); } callback_function() { // done!, called after
我有三列布局。在第三列中,我有两个 div。第一个 div 是固定的。第二个 div 的最小高度为 50px。当第二个 div 中的文本内容增加时,它的高度应该增加到到达第三列底部的点,然后它应该显示
我正在尝试分析/分析核心 JAVA 应用程序。 我正在使用 JConsole Eclipse MAT 。 我在 Perm-Gen 图表中观察到以下情况(在 Windows XP 计算机上记录的 1 小
我有一个按钮附加到父按钮: var parent_button = document.createElement("button"); var child_button = document.crea
在 jquery 中的 div 之间链接动态事件的最佳方法是什么。 我的 HTML 页面: 对于每个点击的 parent ,我想切换它的 child Example :: if p
上下文: 我在阅读 Pomakis 的哈希表实现时出现了一个问题。 Hash lookup 我经常使用 Startpage 来查找更多信息,但仍然一头雾水。 问题: 因为它使用链表来检索 key ,怎
我在想什么 InstrumentationInfo#functionalTest应该实现。对应用环境的启动方式有影响吗? 最佳答案 我在 Android 问题跟踪器上问了这个问题(不幸的是我再也找不到
模偏差是天真地使用模运算来获得小于给定“上限”的伪随机数时出现的问题。 因此,作为一名 C 程序员,我正在使用 arc4random_uniform() 函数的修改版本来生成均匀分布的伪随机数。 问题
我有一个 3 节点 Cassandra 集群,其 key 空间的复制因子为 3: CREATE KEYSPACE demo WITH REPLICATION = { 'class':'Si
元素 tasklist最多可以包含一个 title最多一个 description ,另外任何数字(包括 0)task任何顺序的元素。 天真的方法不适用,因为顺序无关紧要: 或者,我可以明确命名所有
目前,我使用 Azure 服务总线作为平台中不同服务之间的通信和保持数据一致性的手段。但是,假设我的一项服务(订阅者)长时间停机并且无法接收任何事件。突然间,该服务处于不一致的状态。 Azure 服务
我有以下字典: res = [{'name': 'mfi', 'percentage': 100.0, 'tax_base': 1000.0, 'tax_amount': 140.0}, {'name
我有以下字典: res = [{'name': 'mfi', 'percentage': 100.0, 'tax_base': 1000.0, 'tax_amount': 140.0}, {'name
我有两个文件。我正在尝试查找与特定人相关的所有论文。文档保存在它们的集合中,并且正在创建从 Person 到 Paper 的引用,但不是相反。 /** @ODM\Document */ class P
请问有人可以帮我解决 jquery Slider 范围问题吗?我是 jQuery 新手,试图在左/右拖动范围内实现 min(右箭头图标)和 max(左箭头图标)。 价格范围:0 - 1000==(>)
//lets get the auto name set $accepted = 0; $sql = mysql_query("SELECT * FROM ".TBL_FACTIONS." WHERE
我目前正在尝试将大量 XML 更改为 Java 对象,但我一直陷入困境。我尝试过在线复制很多不同的示例,但我似乎永远无法找到正确的方法,而且我发现调试起来非常困难。 我的 XML 看起来像这样
我是一名优秀的程序员,十分优秀!