假设我正在玩10种不同的游戏。对于每个游戏,我都知道获胜的概率,搭售的概率和失败的概率(每个游戏都有不同的概率)。
根据这些值,我可以计算赢得X游戏的概率,丢失X游戏的概率,以及绑定X游戏的概率(X = 0到10)。
我只想弄清楚赢得 W 游戏,绑定 T 游戏以及在玩完所有游戏后输掉 L 游戏的可能性10场比赛......希望比O(3 ^ n)做得更好。例如,赢得7,失去2和打1的概率是多少?
有什么想法吗?谢谢!
编辑 - 这里有一些示例数据,如果只有2个游戏:
游戏1:
第2场比赛:
基于此,我们可以计算出2场比赛之后的概率:
基于这些数字,是否存在一个通用公式,用于查找 W 获胜, T 联系和 L 损失的概率?可能的结果(W-L-T)将是:
答案 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联系的公式:
计算的复杂性
每个幂和阶乘最多具有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;
}