计算一组结果可能性的有效方法?

时间:2010-10-03 02:13:55

标签: algorithm optimization statistics probability dynamic-programming

假设我正在玩10种不同的游戏。对于每个游戏,我都知道获胜的概率,搭售的概率和失败的概率(每个游戏都有不同的概率)。

根据这些值,我可以计算赢得X游戏的概率,丢失X游戏的概率,以及绑定X游戏的概率(X = 0到10)。

我只想弄清楚赢得 W 游戏,绑定 T 游戏以及在玩完所有游戏后输掉 L 游戏的可能性10场比赛......希望比O(3 ^ n)做得更好。例如,赢得7,失去2和打1的概率是多少?

有什么想法吗?谢谢!


编辑 - 这里有一些示例数据,如果只有2个游戏:

游戏1:

  • 胜利:23.3%
  • tie:1.1%
  • 输掉:75.6%

第2场比赛:

  • 胜利:29.5%
  • tie:3.2%
  • 输掉:67.3%

基于此,我们可以计算出2场比赛之后的概率:


  • 0胜:54.0%
  • 1胜:39.1%
  • 2胜:6.9%

  • 0 tie:95.8%
  • 1领带:4.2%
  • 2个领带:0.0%

  • 0亏:8.0%
  • 1损失:41.1%
  • 2损失:50.9%

基于这些数字,是否存在一个通用公式,用于查找 W 获胜, T 联系和 L 损失的概率?可能的结果(W-L-T)将是:

  • 2-0-0
  • 1-1-0
  • 1-0-1
  • 0-1-1
  • 0-2-0
  • 0-0-2

5 个答案:

答案 0 :(得分:3)

这可以通过动态编程完成,我不确定是否有更好的方法,因为游戏是独立的。

拥有4-D阵列,包括胜利,失败,关系和比赛。您可以将赢/输/关系限制为您想要的数字(让这些为W,L,T,W + L + T = G),时间复杂度为O(W * L * T * G),这是有界的由O(G⁴)。

该算法基本上是:

A[][][][] = new double[G+1][W][T][L]
// A[g][w][t][l] is the probability of have w wins, t ties, l losses
// after g games. This can be computed from A[g-1].
// Let P[g][o] be the probability of outcome o for game g
//everything else is initially 0.
A[0][0][0][0] = 1
for g=1..G
 for w=0..W
  for t=0..T
   for l=0..L
    A[g][w][t][l] = A[g-1][w-1][t][l]*P[g][win] // assume out of bounds
                   +A[g-1][w][t-1][l]*P[g][tie] // reference returns 0
                   +A[g-1][w][t][l-1]*P[g][lose]
return A[G][W][T][L]

修改)

我们可以用O(W * L * T * G / max(W,L,T)),即O(G³)来做到这一点。请注意,如果我们在G比赛之后有W胜利和T领带,那么我们必须有L损失。

// we should pick the conditions we loop to be the smallest two.
// here we just use wins and ties.
A[][][][] = new double[G+1][W][T]
A[0][0][0] = 1
for g=1..G
 for w=0..W
  for t=0..T
   A[g][w][t] = A[g-1][w-1][t]*P[g][win] // assume out of bounds
               +A[g-1][w][t-1]*P[g][tie] // reference returns 0
               +A[g-1][w][t]*P[g][lose]
return A[G][W][T]

通过分别计算x wins / ties / loss的概率(O(G)),然后智能地添加/减去它们,也许可以更快地做到这一点,但我还没有找到办法做到这一点

答案 1 :(得分:1)

对于您的示例,您需要考虑结果可能发生的方式。

对于胜利7,输掉2,平局1.有10! / (2!*7!)或360种可能的方式。因此,将所有结果乘以,然后乘以结果的许多排列。

对于所有的胜利,你可以成倍增加,因为只有一个十胜的排列。对于混合,您需要考虑排列。

一般来说,对于这个问题,排列将是10!/(w!*l!*t!),其中w是胜利数,l是损失数,t是关系数。

修改1 请注意,上面仅说明了如何计算排列。总概率是排列次数(pw ^ w * pl ^ l * pt ^ t),其中pw是胜利的概率,pl是亏损,pt平局。 w,l和t是每个的计数。

编辑2 好的,根据新的信息,我不知道这样做的一般方法。您必须手动单独计算每个结果并将它们加在一起。以上是你的两个游戏示例。如果你想找到1胜1平的概率,你必须找到每一种可能的方法来获得1胜和1胜(只有两场)并加起来。

对于初始示例的十场比赛,您将获得符合条件的360个结果。你必须做每个排列并加上概率。 (wwwwwwwllt,wwwwwwwltl等)不幸的是,我不知道有更好的方法来做到这一点。

此外,在你的两场比赛中,对于一场胜利和一场平局,你必须增加赢得第一场比赛的概率,并将第二场比赛与第一场比赛的概率联系起来,然后再获胜。

因此,有九个独立的结果:

W W
W T
W L
T W
T T
T L
L W
L T
L L

答案 2 :(得分:1)

我的区域,统计数据!

你需要计算一个排列的几率,这可以这样做:

O = chanceWin^numWin * chanceTie^numTie * chanceLose^numLose

其中numWin,numLose和numTie是7,2和1,根据你的例子。

现在乘以获胜的排列,即:

O *= 10! / ((10-numWin)! * numWin!)
然后输了:

p = 10-numWin
O *= p! / ((p-numLose)! * numLose!)

然后搭便车:

p = 10-(numWin+numLose)
O *= p! / ((p-numTie)! * numTie!)

现在O是你赢得numWin游戏,输掉numLose游戏并在10场比赛中打出numTie游戏的几率。

答案 3 :(得分:1)

如果您不想超过3 ^ n选项,可以采样 近似:决定N,你的次数希望抽样。运行N个样本,并计算每种类型的结果数量(0胜1负等)。每个结果的概率大概是number_of_samples_resulting_this_outcome / N。

答案 4 :(得分:1)

注意

以下回复仅在通过一系列游戏获胜/失败概率已确定时有效。我误解了这些条件。无论如何,我把它留作简单案例的解决方案。

我得到了W胜利,L输球和N-W-L联系的公式:

alt text

计算的复杂性

每个幂和阶乘最多具有N的阶数,因此该值可以在线性时间中计算,除非我缺少某些要求。

以下Java代码适合我。我还验证了概率总和为1:

public static double p(int w, int l, int t, double pw, double pl) {
    double r = factorial(w+l+t) * Math.pow(pw,w) * Math.pow(pl,l) * Math.pow(1-pw-pl, t);
    r /= factorial(w) * factorial(l) * factorial(t);
    return r;
}

private static long factorial(int n) {
    long res = 1;
    for(int i = 2; i <= n; i++)
        res *= i;

    return res;
}