在给定公平硬币的情况下如何模拟骰子


21

假设给了您一个公平的硬币,并且您想模拟重复翻转一个公平的(六面)骰子的概率分布。我最初的想法是,我们需要选择适当的整数,使2 k = 6 m。所以翻转硬币后ķ倍,我们通过将范围映射由第k比特串长度到管芯的输出编码数[ 0 2 ķ - 1 ]每个的长度为6个的间隔。但是,这是不可能的,因为2 k仅有两个素数,但2 k的素数k,m2k=6mk[0,2k1]m2k包括3。应该有其他简单的方法来执行此操作,对吗?6m


请参阅此问题,以更一般的方式解决该问题。
拉斐尔

这是有关该主题的文章。它说明了如何使用剔除采样以及如何重用“浪费”的位以加速进一步的滚动。
ZeroUltimax 2014年

Answers:


12

要拥有一种比@FrankW所指出的方法稍微有效的方法,但是使用相同的想法,您可以翻转硬币次以得到2 n以下的数字。然后将其解释为一批m次模子翻转,其中m是最大数目,因此6 m < 2 n(如前所述,在这里永远不存在相等性)。如果得到的数字大于或等于6 m,则必须拒绝该值并重复所有n次翻转。n2nmm6m<2n6mn

您可以实现一个函数,该函数通过进行硬币翻转来返回单个骰子翻转,然后缓存以下m 1个骰子翻转请求的结果。nm1

有趣的是,某些值比其他值更好,因为它们的拒绝率较低。这是一个好值的列表(即拒绝率比前一个值低的值):n

n m r
3 1 0.25
8 3 0.15625
13 5 0.05078125
44 17 0.0378308072686
75 29 0.0247036782182
106 41 0.0113974522704
243 94 0.00933096248381
380 147 0.00726015308463
517 200 0.00518501504347
654 253 0.00310553931213
791 306 0.00102171682348

与式获得:

m=nlog32r=13m2n

第一行对应@FrankW的答案,拒绝率为25%。以下数字很不错:n = 13都可以保存在单个整数静态变量中。特别是,n = 13的拒绝率仅为5%,相对于25%而言,这是一个明智的改进,这使其成为可能实施的良好选择。n=8n=13n=13


您不需要6 ^ m,6 * m就足够了。因此,您可以使用5次抛出来获得仅拒绝1/16情况的5位数字。
塔米尔(Taemyr),2014年

相比于3次投掷25%,拒绝13次投掷5%的拒绝率是可怕的。因为在0.390625%的情况下,25%的3次抛掷只会拒绝4次(即花费12次以上)。
Taemyr 2014年

@Taemyr一个5位数字可以表示32个不同的值,它使您可以表示一个骰子(因为两个骰子有36种可能性)。因此,只有6/32的值可以接受,拒绝率为27/32 = 84%
Emanuele Paolini

@Taemyr:拒绝的速率Ñ的是,在平均每一批抛手段Ñ掷获取与概率拒绝- [R 。因此,平均而言,每次抛掷均以相同的比率r(不取决于n)被拒绝。rnnrrn
2014年

是。并使用FrankW的方法(每批3次抛投的拒绝率为25%),在不迟于第4批的情况下接受1-0.00390625的可能性。
塔米尔(Taemyr)2014年

29

您可以做的是采用一种称为拒绝采样的方法:

  • 翻转硬币3次,并将每次翻转解释为一点(0或1)。
  • 串联的3个比特,在给二进制数[0,7]
  • 如果该数量是在,把它作为一个模辊。[1,6]
  • 否则,即结果为7,请重复翻转。07

每组中有 8种可能的结果导致终止,需要超过l组翻转才能获得掷骰的概率为1668l。因此,该方法在实践中是有效的。(168)l=14l

改进之处:

07

@Emanuele Paolini解释说,如果需要多个压模辊,如何减少重新轧辊的数量。


这种方法不会像真正的d6那样产生更大的集中趋势吗?
Red_Shadow 2014年

3
k[0..2k1]

如果您对拒收范围颇为狡猾,在这种情况下实际上很容易使用它来减少拒收情况下必要的硬币翻转次数。
Mooing Duck

@MooingDuck您可以决定是否在两次掷球后放弃结果:如果是0,0 0,1或1,0,则再次掷球至最后一位,否则重新开始
棘手怪胎

1
k

7

拒绝采样的替代方法(如FrankW的答案所述)是使用缩放算法,该算法将[7,8]的答案考虑在内,就好像是另一次硬币掷硬币一样。

mathforum.org上有一个非常详细的解释,其中包括算法(它NextBit()掷出您的硬币)。

用普通硬币投掷骰子的情况(采样2→6)比通用算法更容易。您只需将失败(7或8)作为另一个硬币输入,然后再进行两次翻转。


2

使用dM模拟dN滚动的另一种方法(在使用d2询问特定问题d6的情况下)是将间隔[0,1)划分为长度为N / [N,[0, 1 / N),[1 / N,2 / N),...,[(N-1)/ N,N)。

使用dM在[0,1)中生成基本M分数0.bbbb...。如果该值落在[(i-1)/ N,i / N)中,则将i作为dN的卷。请注意,您只需要生成分数的足够的基M位数即可确定分数所在的间隔。


需要使终止条件更加精确。如果我一次抛硬币,最终得到的二进制分数为0.0或0.1(即½),两者都落入一个区间(在这种情况下,分别对应于0和3)。您需要将生成的分数视为一个范围,并且当整个范围在单个时间间隔内时就停止。我确定这就是您的意图,但我认为不清楚。
rici

1

改善拒绝采样的可能更简单的解释。

我正在提供此解释,因为它可能有助于简化某些情况下对概率的理解或分析。

FrankW建议使用拒绝采样,将硬币翻转三遍,如果结果在正确的范围内,则保持结果;否则,重复三遍翻转,直到成功为止。

Ángel建议在每个试验中保存一次翻转,用之前三组中两个未使用的值剩余的二元选择代替它。

这实际上意味着在前三个翻转中产生了一点信息,而这并不需要产生。更准确地说,您应该只需要掷硬币两次就可以知道当前的掷骰是否成功。

知道当前的一组翻转是否成功是唯一重要的概率,因为解释一组成功的翻转与概率无关。这可以在该组的所有翻转完成之前知道。

这可以通过至少两种方式来实现,或更准确地说,通过翻转的两种不同的解释来实现。可能还有其他。

成对分组结果

想法是仅考虑由任意三个双翻转配置表示的三个值(1,2),(3,4)和(5,6),例如TT,TH,HT。然后,您可以使用两次翻转应用拒绝采样,每当获得故障配置HH时重复一次。

一旦获得了三种成功配置中的一种,就可以再次翻转硬币,以决定是否应该采用对应货币对的第一个或第二个值。

早期发现翻转失败

这个想法是对三重翻转配置使用略有不同的读数。如果将Head和Tail解释为1和0,则配置应对应于二进制解释加1。也就是说,TTT(即000)对应于1,HTH(即101)对应于6,HHT(即110)与HHH(即111)对应于7和8,或[1,6]以外的任何值。

然后我们知道翻转集仅在前两次翻转中是成功还是失败。如果它们产生HH,则翻转集将失败,而与最后一次翻转无关。因此可以跳过。

我认为总是可以将早期检测作为一种解释,但是根据模拟骰子上面孔的数量,可能会在无数次翻转之后进行故障检测。

例如,对于10个面子骰子,原则上您需要4组翻转的翻转集,其中6种配置对应于失败。诀窍是使所有故障配置都位于二进制值序列的高端,如下所示:

TTTT  0000   1
HTTT  1000   9
HTTH  1001  10
HTHT  1001  11
HTHH  1011  12
HHTT  1100  13
HHHH  1111  16

成功的配置对应于范围[1,10],失败的则对应于范围[11,16]。

然后,当前两个翻转给出HH或前三个翻转给出HTH时,您将失败,而不必尝试缺少该集合的翻转。

如果没有失败,则只需终止一组翻转即可。


1

有两种众所周知的方法。一种是“拒绝采样”。例如,使用三位从六个值中选择一个,然后再次尝试两个额外的样本。或使用14位(8192个值)从1到6中选择5个值(可能性为7776),在256种情况下,再尝试13种。

另一种方法是使用压缩/解压缩算法的解压缩部分:通过算术编码,可以压缩几乎没有冗余的从1到6的随机值序列。随机生成压缩序列,然后将其解压缩。这要复杂得多,但是实际上将不需要任何其他随机数。


0

如果解释多余,对不起。我不确定要涉及多少细节或该概念易于理解。

假设您有三个硬币(普通硬币)。如果您将增量值分配给每个硬币的每一面,则将有六个值。

像这样:在第一个硬币上,正面为1,在后面为2。在第二个硬币上,正面为3,在后面为4。在第三个硬币上,正面为5,在后面为6。

翻转硬币会留下一组三个数字,即当前的一组数字。现在,您的当前集合将成为您先前的集合,并且您将重复此过程以获取新的三个数字集合。

继续执行此操作,直到从您的当前号码到先前的号码中只有一个号码匹配。那是你的电话号码。

因此,如果您获得了当前集合的[头,尾,头],则为[1,4,5]。现在您再次翻转它们,当前设置为[2,4,5]。两场比赛。不好。再试一遍。您得到[2,3,6]。只有一场比赛。你的人数是两个。

任何给定的号码都会有相等的机会出现,但并不是特别划算,因为只有3/32的变化可以使任何给定的一组对成功(只有一场比赛)。因此,平均而言,该算法必须重复大约十次。而且,它不容易推广到奇数管芯。

至少,这可能是值得深思的。非常有趣的问题。


4
lognn12n2n/2n

0

我将掷硬币三次,并将结果解释为二进制数,拒绝超出范围的结果。

例如,让heads为1,tails为0。如果将其翻转3次,得到head,tails和heads,则将具有二进制101,即十进制5。HHT = 110b =6。TTT= 000b = 0且HHH = 111b = 7,这两个值均超出范围,将被拒绝,您将需要取整所有数字。


1
那只是弗兰克的答案。
拉斐尔

2
@Raphael实际上,这是Frank回答的严格子集,因为Frank解决了预期的运行时间。
David Richerby 2014年

0

不幸的是,一个人不能(忠实地)使用(一个或多个)公平硬币来模拟(公平)死亡。

62

但是,人们可以用一个公平的“三币”来做到这一点(如果可以使用这样的术语)。表示具有3个结果的硬币。还有一个简单的2枚硬币,因此这2枚硬币的联合空间与骰子的事件空间完全匹配。

拒绝采样(如某些答案中所述)确实可以提供近似的模拟。但是它仍然会存在一定数量的错误或概率不匹配(在有限时间内)。因此,如果要实际匹配这两个系统的事件空间,则在某些情况下它将无法正常工作。

在概率模拟中(以拒绝采样为例),生成的典型序列确实确实表现出相对的基本概率(在这种情况下,是模具的事件空间)。但是(如评论中所述),这些典型序列中的每一个都可以包含完全相同结果的任意长子序列。这意味着,为了使用拒绝采样(在某些情况下),它可能会花费很长时间,或者由于事件空间某些部分的过多表示或不足表示,生成的分布将有偏差(即不公平) 。如果不是这种情况,则可以使用确定性算法,该算法将与骰子和硬币的事件空间完全匹配(在维度上不匹配)。


评论不作进一步讨论;此对话已转移至聊天
吉尔斯(Gillles)“所以-别再作恶了” 2014年

@Gilles,尽管进行了所有解释和闲聊(关于正确性),但仍然存在糟糕的负面投票:p
Nikos M.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.