在N次成功之前,我该如何模拟翻转?


17

你和我决定玩一个游戏,大家轮流掷硬币。第一位总共翻转10个头的玩家将赢得比赛。自然,关于谁应该先走有一个争论。

此游戏的模拟结果显示,前一个掷骰的玩家比第二个掷骰的玩家赢6%(第一个掷骰的玩家大约有53%的时间获胜)。我有兴趣对此进行建模分析。

这不是二项式随机变量,因为没有固定的试验次数(直到有人得到10个脑袋时才翻转)。我该如何建模?它是负二项式分布吗?


为了能够重新创建我的结果,这是我的python代码:

import numpy as np
from numba import jit


@jit
def sim(N):

    P1_wins = 0
    P2_wins = 0

    for i in range(N):

        P1_heads = 0
        P2_heads = 0
        while True:

            P1_heads += np.random.randint(0,2)

            if P1_heads == 10:
                P1_wins+=1
                break

            P2_heads+= np.random.randint(0,2)
            if P2_heads==10:
                P2_wins+=1
                break
    return P1_wins/N, P2_wins/N


a,b = sim(1000000)

3
当你掷硬币直到r故障,然后看看在完成这样的实验在这之前发生成功的次数的分布,那么这是通过定义负二项分布
蒂姆

2
我无法复制2%的值。我发现的第一个球员赢得53.290977425133892%的时间。
whuber

1
@whuber是的,我相信你是对的。我进行模拟的次数少于应有的次数。我的结果与你的相称。
德米特里Pananos

1
如果一个人有53%的时间获胜,那么另一个人应该是47%,那么描述中是否不应显示“第一个玩家比第二个玩家赢6%多”或“一半以上的玩家赢3%”?不(按照目前的说法)“比第二名多3%”
JesseM

3
你收到来自FiveThirtyEight这个问题谜语快车
foutandabout

Answers:


19

尾的数量的实现之前的分布的头是负二项与参数101 / 2。让˚F是概率函数和生存函数:每个ñ 0˚F ñ 是玩家的机会ň前尾巴10头和g ^ ñ 是玩家的机会ñ之前或更多的尾巴10头。10101/2fGn0f(n)n10G(n)n10

因为玩家独立地滚动,机会第一玩家获胜与恰好滚动尾部被由第二玩家辊上的机会,机会相乘得到Ñ或多个尾部,等于˚F Ñ ģ Ñ nnf(n)G(n)

求和所有可能给人的第一玩家的获胜几率为n

ñ=0FñGñ53.290977425133892

大约是一半时间的3%

通常,用任何正整数m代替,答案可以根据超几何函数给出:它等于10m

1/2+22m12F1(m,m,1,1/4).

当使用偏头硬币的机会为下,这可以概括为p

12+12(p2m)2F1(m,m,1,(1p)2).

这是R一百万个此类游戏的模拟。报告的估计值为。将其与理论结果进行比较的二项式假设检验的Z得分为0.843,差异不明显。0.53250.843

n.sim <- 1e6
set.seed(17)
xy <- matrix(rnbinom(2*n.sim, 10, 1/2), nrow=2)
p <- mean(xy[1,] <= xy[2,])
cat("Estimate:", signif(p, 4), 
    "Z-score:", signif((p - 0.532909774) / sqrt(p*(1-p)) * sqrt(n.sim), 3))

1
就像乍看之下可能并不明显一样,我们的答案在数值上也一致:(.53290977425133892-.5)* 2本质上是我给出的概率。
Dougal

1
@Dougal感谢您指出这一点。我查看了您的答案,看到,并且知道它与问题中要求的答案的形式不一致,因此我不知道您的计算正确。通常,最好以要求的形式将任何问题的答案框起来,如果可能的话:这样可以很容易地识别出正确的时间,并且可以轻松地比较答案。6.6%
whuber

1
@whuber我在回应短语“此游戏的模拟显示,先翻转的玩家比第二翻转的玩家赢2%(编辑:模拟更多游戏后,赢3%)”。我将“多赢2%”解释为;正确的值确实是6.6%。我不确定有什么方法可以解释“多赢2%”的意思是“有52%的机会赢”,尽管这显然是我们的初衷。Pr(A wins)Pr(B wins)=2%
Dougal

@Dougal我同意OP的描述令人困惑甚至错误。但是,代码和他的结果清楚地表明,他的意思是“比一半时间多出3%”,而不是“比其他玩家多3%”。
Whuber

1
@whuber同意。不幸的是,我在发布代码之前回答了这个问题,并且自己没有运行模拟。:)
Dougal

15

我们可以像这样对游戏进行建模:

  • 玩家A反复翻转硬币,得到结果A1,A2,,直到他们得到共计10头。让10头时指数是随机变量X
  • 玩家B也是一样。设第10个磁头的时间索引为随机变量Y,它是X的iid副本。
  • 如果XY,玩家A获胜; 否则,玩家B获胜。即,
    Pr(A wins)=Pr(XY)=Pr(X>Y)+Pr(X=Y)Pr(B wins)=Pr(Y>X)=Pr(X>Y).

因此,胜率的差距为

Pr(X=Y)=kPr(X=k,Y=k)=kPr(X=k)2.

正如您所怀疑的那样,X(和Y)基本上是根据负二项分布分布的。表示法各不相同,但在Wikipedia的参数化中,正面为“失败”,背面为“成功”。在实验停止之前,我们需要r=10 “失败”(正面),成功概率p=12。然后,“成功”的数量为X10,具有

Pr(X10=k)=(k+9k)210k,
and the collision probability is
Pr(X=Y)=k=0(k+9k)222k20,
which Mathematica helpfully tells us is 7649952511622614676.6%.

Thus Player B's win rate is Pr(Y>X)46.7%, and Player A's is 619380496116226146753.3%.


the heads need not be in a row, just 10 total. I assume that is what you are fixing.
Demetri Pananos

6
(+1) I like this approach better than the one I posted because it is computationally simpler: it requires only the probability function, which has a simple expression in terms of binomial coefficients.
whuber

1
I've submitted an edit replacing the last paragraph questioning the difference from the other answer with an explanation of how their results are actually the same.
Monty Harder

1

Let Eij be the event that the player on roll flips i heads before the other player flips j heads, and let X be the first two flips having sample space {hh,ht,th,tt} where h means heads and t tails, and let pijPr(Eij).

Then pij=Pr(Ei1j1|X=hh)Pr(X=hh)+Pr(Ei1j|X=ht)Pr(X=ht)+Pr(Eij1|X=th)Pr(X=th)+Pr(Eij|X=tt)Pr(X=tt)

Assuming a standard coin Pr(X=)=1/4 means that pij=1/4[pi1j1+pi1j+pij1+pij]

solving for pij, =1/3[pi1j1+pi1j+pij1]

But p0j=p00=1 and pi0=0, implying that the recursion fully terminates. However, a direct naive recursive implementation will yield poor performance because the branches intersect.

An efficient implementation will have complexity O(ij) and memory complexity O(min(i,j)). Here's a simple fold implemented in Haskell:

Prelude> let p i j = last. head. drop j $ iterate ((1:).(f 1)) start where
  start = 1 : replicate i 0;
  f c v = case v of (a:[]) -> [];
                    (a:b:rest) -> sum : f sum (b:rest) where
                     sum = (a+b+c)/3 
Prelude> p 0 0
1.0
Prelude> p 1 0
0.0
Prelude> p 10 10
0.5329097742513388
Prelude> 

UPDATE: Someone in the comments above asked whether one was suppose to roll 10 heads in a row or not. So let Ekl be the event that the player on roll flips i heads in a row before the other player flips i heads in a row, given that they already flipped k and l consecutive heads respectively.

Proceeding as before above, but this time conditioning on the first flip only, pk,l=11/2[pl,k+1+pl,0] where pil=pii=1,pki=0

This is a linear system with i2 unknowns and one unique solution.

To convert it into an iterative scheme, simply add an iterate number n and a sensitivity factor ϵ:

pk,l,n+1=1/(1+ϵ)[ϵpk,l,n+11/2(pl,k+1,n+pl,0,n)]

Choose ϵ and pk,l,0 wisely and run the iteration for a few steps and monitor the correction term.

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.