赢得比赛的概率 K 场比赛最好的系列 N 场比赛

机器算法验证 r 可能性
2022-02-02 01:33:55

考虑体育/竞赛中的“五局三胜”系列赛,第一支赢得 3 场比赛的球队将赢得该系列赛。所以N=5,K=3。其中概率w = p(team A winning game)l = p(team A losing game)假设这些概率在系列期间没有变化。

当我第一次想到这一点时,我错误地尝试添加赢得 3/3、3/4 和 3/5 游戏的个人概率:

wrong = function(w) {      
  p = dbinom(3,3,w) + dbinom(3,4,w) + dbinom(3,5,w)       
  return(p)
}

wrong(.9)
# 1.0935

显然,问题在于存在冗余,因为连续 3 场获胜,WWW 使任何第 4 场和第 5 场比赛的结果都过时了。即 WWWLW 和 WWWWL 是不可能的。

去除冗余后,这些是可能的排列:

win = function(w) {
  l = 1-w
  p = w*w*w + 
    w*w*l*w + w*l*w*w + l*w*w*w + 
    l*l*w*w*w+ l*w*l*w*w+ l*w*w*l*w+  
    w*l*l*w*w+ w*l*w*l*w+
    w*w*l*l*w

  return(p)
}

win(.9)
# 0.99144

win(.9) + win(.1)
# 1

手动输入排列会很快失去控制,即赢得 N = 7 个游戏系列、9 个游戏系列等。通常,wrong()需要如何修改函数才能获得正确的概率?

4个回答

对于这个问题,您可以使用负二项分布。

如果 X 分布为 NegBin(n, w),则如果赢得任何给定游戏的概率为 w,则 X 是玩家在赢得 n 个游戏之前输掉的游戏数。

所以,dnbinom(q = 2, size = 2, prob = w)是玩家在赢得 2 场比赛之前总共输掉 2 场比赛的概率。

然后,pnbinom(q = 2, size = 3, prob = w)是玩家在赢得 3 场比赛之前输掉 2 场或更少的概率。这等于赢得 5 个系列中的 3 个的概率。

一般来说,赢得最佳 n-out-of-(2n-1) 系列的概率可以用 来计算pnbinom(q = n-1, size = n, prob = w)

## w is the probability of winning any individual game
## k is the number of wins needed to win the series (3 in a best 3 of 5 series)
win <- function(w, k){
  return (pnbinom(q = k - 1, size = k, prob = w))
}

win(0.9, 3)
## 0.99144

这很有趣。让我们演示使用n = 3需要 2 次获胜才能成为获胜者的情况。我们可以先确定哪些组合可用

n = 3L
lst = replicate(n, 0:1, simplify = FALSE)
combos = do.call(expand.grid, lst)
combos

  Var1 Var2 Var3
1    0    0    0
2    1    0    0
3    0    1    0
4    1    1    0
5    0    0    1
6    1    0    1
7    0    1    1
8    1    1    1

正如您所指出的,其中一些组合是不可能的。当 等于 2 时,我们特别感兴趣rowSums()。使用它,我们可以确定哪些组合实际上是可能的。

possible_combos = combos[rowSums(combos) == ceiling(n / 2), ]
possible_combos

  Var1 Var2 Var3
4    1    1    0
6    1    0    1
7    0    1    1

我们的最后一步是根据我们可能的贡献计算每个贡献。我们知道这w^2将在每次计算中。l部分比较复杂在我们的第一个可能的组合中,l没有任何贡献。我们可以用来max.col(..., ties.method = "last")计算发生了多少ls:

losses = max.col(possible_combos, ties.method = "last") - ceiling(n / 2)
losses
# [1] 0 1 1

w = 0.9
l = 1 - w
wins_p = w ^ ceiling(n / 2)
losses_p = ifelse(losses == 0L, 1, l ^ losses)

p = sum(wins_p * losses_p)
p
# [1] 0.972

为了概括这一点,我们可以将其用作基于nand的函数w

right = function(n, w) {
  lst = replicate(n, 0:1, simplify = FALSE)
  combos = do.call(expand.grid, lst)
  possible_combos = combos[rowSums(combos) == ceiling(n / 2), ]
  losses = max.col(possible_combos, ties.method = "last") - ceiling(n / 2)

  l = 1 - w
  wins_p = w ^ ceiling(n / 2)
  losses_p = ifelse(losses == 0L, 1, l ^ losses)

  sum(wins_p * losses_p)
}

right(5, 0.9)
# [1] 0.99144
right(5, 0.9) + right(5, 0.1)
# [1] 1

实际上你快到了,但你应该知道有四场和五场比赛获胜的情况。

win <- function(w) dbinom(3,3,w)+w*dbinom(2,3,w) + w*dbinom(2,4,w)

或紧凑的解决方案

win <- function(w) w*sum(mapply(dbinom,2,2:4,w))

这样

> win(0.9)
[1] 0.99144

解释: 鉴于赢得系列赛所需的比赛数量取决于最后一场胜利:

  • 如果需要 3 场比赛:前两场比赛应该都赢,这样概率。w**3(等价于dbinom(3,3,w)dbinom(2,2,w)*w

  • 如果需要4场比赛:前三场比赛中应该有2胜1负,这样概率。choose(4,2)*w**2*(1-w)*w(相当于dbinom(2,4,w)*w

  • 如果需要 5 场比赛:前四场比赛中应该是 2 胜 2 负,这样概率。choose(4,2)*w**2*(1-w)**2*w(相当于dbinom(2,4,w)*w


更新:概括win

对于任何N(偶数或奇数),广义函数win可以定义如下

win <- function(w, N) w*sum(mapply(dbinom,ceiling((N-1)/2),ceiling((N-1)/2):(N-1),w))

N但是,对于大s ,上述方法效率不高。相反,@RyanFrost提到的负二项式分布方法更适用于 s 较大的情况N,即

win <- function(w, N) pnbinom(floor((N-1)/2), ceiling((N+1)/2), w)

例子

> win(0.9,5) # needs at 3 wins out of 5 games
[1] 0.99144

> win(0.9,6) # needs at 4 wins out of 6 games
[1] 0.98415

它是一个二项分布:

dbinom(3,5,0.9) + dbinom(4,5,0.9)+dbinom(5,5,0.9) = 0.99144

原因是这样的,你只需要考虑总空间,即使已经有 3 胜或 4 胜,让我们假设事件继续进行,我们可以将可能的事件写成:

w.w.w : w.w.w.w.k , w.w.w.k.k , w.w.w.k.w, w.w.w.w,w
w.w.l.w : w.w.l.w.l, w.w.w.l.w
l.w.w.w : l.w.w.w.1 , l.w.w.w.w

等等..

那些写成包含 3 胜的例子 (wwlwl) 将是 5 的一部分,在二项式中选择 3。

在5个赛事的W/L总空间中,我们需要的是3胜、4胜和5胜,以包括所有可能导致球队获胜的事件(即使在现实生活中,第4或第5场比赛将不会发生)