我正试图找出'苏西'赢得比赛的可能性。
'苏西'赢得比赛的可能性= 0.837
“鲍勃”赢得比赛的可能性= 0.163
如果第一个赢得n场比赛的人赢了一场比赛,那么苏的最小值是多少,以便有超过0.9的机会赢得比赛?
到目前为止,我有这段代码:
import itertools
W = 0.837
L = 0.163
for product in itertools.product(['W','L'], repeat=3): #3=number of games
print product
打印哪些:
('W', 'W', 'W')
('W', 'W', 'L')
('W', 'L', 'W')
('W', 'L', 'L')
('L', 'W', 'W')
('L', 'W', 'L')
('L', 'L', 'W')
('L', 'L', 'L')
然后我想用这些结果来计算'苏西'赢得整场比赛的概率。
我已经在纸上解决了这个问题,玩的游戏越多,'Susie'赢得比赛的机会就越大。
答案 0 :(得分:1)
您可以使用词典来表示概率:
import itertools
import operator
probabilities = {'W':0.837, 'L':0.163}
for product in itertools.product(['W','L'], repeat=3): #3=number of games
p = reduce(operator.mul,
[probabilities[p] for p in product])
print product, ":", p
reduce
函数使用第一个参数中给出的函数累积列表的所有元素 - 这里我们通过乘法累加它们。
这为您提供了每个事件序列的概率。从这里你可以很容易地选择哪一个是“苏西赢得比赛”,并总结概率。这样做的一种可能性是:
import itertools
import operator
probabilities = {'W':0.837, 'L':0.163}
winProbability = 0
for product in itertools.product(['W','L'], repeat=3): #3=number of games
p = reduce(operator.mul,
[probabilities[p] for p in product])
if product.count('W') > 1: #works only for 3 games
winProbability += p
print "Susie wins:", product, "with probability:", p
else:
print "Susie looses:", product, "with probability:", p
print "Total probability of Susie winning:", winProbability
这个条件仅适用于3
个游戏,但我真的把这个游戏留给你了 - 很容易将其归结为n
个游戏:)
答案 1 :(得分:1)
您还需要循环n
的值。另请注意,“首先n
”与“2n-1
最佳”相同。所以我们可以说m = 2 * n - 1
并看看谁赢得了那场比赛中的大多数比赛。 max(set(product), key=product.count)
是一种简短而不透明的方法,可以解决谁赢得了最多的比赛。此外,当您可以直接将值存储在元组中时,为什么还要用字符串表示概率,然后使用字典来读取它们。
import itertools
pWin = 0 #the probability susie wins the match
n = 0
while pWin<0.9:
n += 1
m = 2 * n - 1
pWin = 0
for prod in itertools.product([0.837,0.163], repeat=m):
#test who wins the match
if max(set(prod), key=prod.count) == 0.837:
pWin += reduce(lambda total,current: total * current, prod)
print '{} probability that Susie wins the match, with {} games'.format(pWin, n)
答案 2 :(得分:0)
我被@ desired_login的观点所吸引,但我想我会尝试计算排列而不是迭代它们:
import sys
if sys.hexversion >= 0x3000000:
rng = range # Python 3.x
else:
rng = xrange # Python 2.x
def P(n, k):
"""
Calculate permutations of (n choose k) items
"""
if 2*k > n:
k = n - k
res = 1
for i in rng(k):
res = res * (n-i) // (i+1)
return res
Ps = 0.837 # Probability of Susie winning one match
Px = 0.980 # Target probability
# Probability of Susie winning exactly k of n matches
win_k = lambda n,k: P(n, k) * Ps**k * (1.0-Ps)**(n-k)
# Probability of Susie winning k or more of n matches
win_k_or_more = lambda n,k: sum(win_k(n, i) for i in rng(k, n+1))
def main():
# Find lowest k such that the probability of Susie winning k or more of 2*k - 1 matches is at least Px
k = 0
while True:
k += 1
n = 2*k - 1
prob = win_k_or_more(n, k)
print('Susie wins {} or more of {} matches: {}'.format(k, n, prob))
if prob >= Px:
print('At first to {} wins, Susie has >= {} chance of winning the match.'.format(k, Px))
break
if __name__=="__main__":
main()
对于Px = 0.98,这导致
Susie wins 1 or more of 1 matches: 0.837
Susie wins 2 or more of 3 matches: 0.9289544940000001
Susie wins 3 or more of 5 matches: 0.9665908247127419
Susie wins 4 or more of 7 matches: 0.9837066988309756
At first to 4 wins, Susie has >= 0.98 chance of winning the match.
此算法的运行时类似于O(n ^ 3),而其他算法则为O(2 ^ n)。