淘汰概率


9

淘汰赛是一种篮球比赛,球员轮流投篮。它按两人比赛的顺序进行,每场比赛都有可能“淘汰”其中一名球员。

假设球员A B C D和他们的投篮机会和制造篮筐的机会0.1 0.2 0.3 0.4分别与比赛中的其他球员无关。两位选手在该行的前面,AB“战斗”。由于A先行,他是后卫,在被淘汰出局的危险,并且B攻击者,而不是立即消除危险。A首先射击。如果成功A,则A已经成功防御,并前进到了队伍的后部。该行将更改为B C D A。如果A没有成功,则B射击。如果B成功,则出线AB转到行尾,因此行变为C D B。如果两者都不A如果没有B成功,则重复此过程,并A再次射击,直到AB做出一个篮子。

假设线路更改为B C D AA已成功防御)。现在,BC“战斗”B作为后卫,并且C是攻击者。重复此过程,直到只剩下一个人为止。那个人是赢家。

您的任务是计算每个人赢得一篮子机会的获胜概率。

输入

数字列表,例如0.1 0.20.5 0.5 0.5 0.5,其中第n个数字是第n个个玩家上篮。您可以采用任意格式的输入,包括作为函数的参数。

输出量

数字列表,其中第n个数字是第n个玩家赢得比赛的机会。您的数字至少在90%的时间内必须精确到至少两位小数。这意味着您可以使用基于仿真的方法。但是,如果您的代码不是基于仿真的(可以保证返回正确的答案至少到小数点后6位),那么您的分数将减少30%。

之间的示例0.5 0.5:呼叫玩家AB。设pA获胜的概率。A拥有2/3的成功卫冕的机会(因为有一个1/2机会A得分,一个1/4机会,A命中和B得分和1/4机会都错过并重复上述过程)。如果A未能防守,他将被淘汰并B获胜。如果A防御,则该行变为B A。由于情况是对称的,因此A获胜的概率为(1 - p)。我们得到:

p = 2/3 * (1 - p) + 1/3 * 0。解决,我们得到p = 2/5。输出应为2/5 3/50.4 0.6

我没有足够的机率做更复杂的例子。

如果您需要更多的测试用例,请参考以下几个示例:

0.1 0.2 0.3 0.4 --> 0.01 0.12 0.25 0.62
0.99 0.99 --> 0.5 0.5 (it's not exact, but if you round to two decimal places, you get 0.5 and 0.5)

Answers:


4

CJam(84 80个字符* 0.7 = 56)

{_,({_,,{_2$m<(;(+Q0\)\++m>\}%)_(+.{X2$-*_@+/}1\{1$*\1$-}%)1\-f/.f*:.+}{,da}?}:Q

在线演示。这是一个递归函数,它采用一个双精度数组并返回一个双精度数组。在线演示包含少量脚手架,以执行功能并格式化输出以进行显示。

解剖

基本原则是,如果n > 1剩下任何一个玩家,则其中一个必须是下一个要淘汰的玩家。而且,此后发生的队列顺序仅取决于队列的初始顺序以及被淘汰的人。这样我们就可以n递归调用,计算每种情况下每个玩家的获胜概率,然后只需要适当地加权并相加即可。

我将输入概率标记为[p_0 p_1 ... p_{n-1}]。让f(a,b)表示a无法防御的概率b。在任何给定的圆,该概率a防守是成功的p_a,即概率ba出来的(1-p_a)*p_b,那它关系到新一轮的概率(1-p_a)*(1-p_b)。我们可以做一个几何级数的显式总和,也可以争论两个几何级数彼此成正比来推论这一点f(a,b) = (1-p_a)*p_b / (p_a + (1-p_a)*p_b)

然后,我们可以将水平提高到整轮。第一名玩家被淘汰出局的机率是f(0,1);第二个玩家被淘汰的机率是(1-f(0,1)) * f(1,2); 第三人是(1-f(0,1)) * (1-f(1,2)) * f(2,3); 直到最后一个被淘汰\prod_i (1-f(i,i+1)) * f(n-1,0)。关于几何级数的相同论点允许我们将这些概率用作权重,归一化系数为1 / \prod_i f(i, i+1 mod n)

{                   e# Define a recursive function Q
  _,({              e# If we have more than one person left in the line...
    _,,{            e#   Map each i from 0 to n-1...
      _2$m<         e#     Rotate a copy of the probabilities left i times to get [p_i p_{i+1} ... p_{n-1} p_0 ... p_{i-1}]
      (;(+          e#     i fails to defend, leaving the line as [p_{i+2} ... p_{n-1} p_0 ... p_{i-1} p_{i+1}]
      Q             e#     Recursive call
      0\)\++        e#     Insert 0 for the probability of i winning and fix up the order
      m>\           e#     Rotate right i times and push under the list of probabilities
    }%
    )               e#   Stack: [probs if 0 knocked out, probs if 1 knocked out, ...] [p_0 p_1 ...]
    _(+.{           e#   Duplicate probs, rotate 1, and pointwise map block which calculates f(a,b)
      X2$-*_@+/     e#     f(a,b) = (1-p_a)*p_b / (p_a + (1-p_a)*p_b)  TODO is the d necessary?
    }
    1\{1$*\1$-}%    e#   Lift over the list of f(a,b) a cumulative product to get the weights  TODO is the d necessary?
    )1\-f/          e#   Normalise the weights
    .f*             e#   Pointwise map a multiplication of the probabilities for each case with the corresponding weight
    :.+             e#   Add the weights across the cases
  }{,da}?           e# ...else only one left, so return [1.0]
}:Q
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.