Вычислить вероятность победы в сете с точным счетом, если вероятность выиграть гейм величина зависимая. теннис
Дано: p - вероятность выиграть первый гейм игроком1 (не зависимо кто подает), х - коэффициент, характерезующий изменение вероятности p в зависимости от того кто выиграл предыдущий гейм. Зависимость простая: если игрок1 выиграл предыдущий гейм, то увеличим вер-ть выиграть следующий гейм p_new = p + х * q, где q = 1 - p, т.е. это вероятность выиграть гейм игроком2. Если игрок1 проигрывает, то его шансы снижаются p_new = p - x * p.
Немного о правилах тенниса, которые принимаются для данной задачи: для победы в сете теннисист должен выиграть минимум шесть геймов с разницей минимум в два гейма: 6-0, 6-1, 6-2, 6-3 и 6-4. Если счет в сете доходит до 5-5, соперники играют до победы в 7 геймах, т.е. возможные варианты победить это 7-5 или 7-6.
Если бы вероятность победы в гейме была постоянной, задача сведась к подсчету числа сочетай выигранных геймов. Тогда победа со счетом 6-0: win6_0 = p ** 6 и далее
win6_1 = 6 * p ** 6 * q win6_2 = 21 * p ** 6 * q ** 2, число сочетаний 2 из 7, т.к. последний гейм всегда выигрывает победитель сета win6_3 = 56 * p ** 6 * q ** 3 win6_4 = 126 * p ** 6 * q ** 4 win7_5 = 252 * p ** 7 * q ** 5 win7_6 = 504 * p ** 7 * q ** 6
Теперь посмотрим, что получается если вер-ть выиграть гейм меняется. Например, для победы со счетом 6-1 будет 6 комбинаций. Если p1 = p, q1 = 1 - p1 и т.д., то комбинации будут следующие
q1 * p2 * p3 * p4 * p5 * p6 * p7, p1 * q2 * p3 * p4 * p5 * p6 * p7, p1 * p2 * q3 * p4 * p5 * p6 * p7, p1 * p2 * p3 * q4 * p5 * p6 * p7, p1 * p2 * p3 * p4 * q5 * p6 * p7, p1 * p2 * p3 * p4 * p5 * q6 * p7
Разберем вторую комбинацию
p1 = p q2 = q1 - x * q1 p3 = p2 - x * p2 p4 = p3 + x * q3 p5 = p4 + x * q4 p6 = p5 + x * q5 p7 = p6 + x * q6
и в каждой комбинации вероятности p1, q1, p2, q2, ... будут отличаться
Помогите организовать вот эти вот вычисления на pythone или VBA.
Ответы (2 шт):
Если я правильно понял правила, то можно сообразить что-то подобное.
Функция принимает начальную вероятность выигрыша, коэффициент поправки, счёт, и вероятность варианта (изначально единица).
Условие окончания - уменьшение счёта побед до нуля.
При этом счётчик проигрышей должен быть нулевым за счёт условия во втором if (условие того, что последняя партия обязана быть выигрышной)
Третий if разрешает проигрыши, если их счётчик не исчерпан
В рекурсивный вызов передаётся модифицированная вероятность выигрыша, изменённые счётчики, и накопленная на данный момент вероятность текущего варианта.
def tennis(p, x, wins, looses, prob=1.0):
if wins == 0:
return prob
res = 0.0
if looses == 0 or wins > 1:
res += tennis(p + x*(1-p), x, wins-1, looses, prob*p)
if looses > 0 :
res += tennis(p - p*x, x, wins, looses-1, prob*(1-p))
return res
s = 0
p = 0.6
x = 0.1
for l in range(7):
w = 6 + l//5
f = tennis(p, x, w, l)
s += f
print(w, l, f)
print('sum =',s)
6 0 0.10359427536442602
6 1 0.14328407813335833
6 2 0.13895348110712838
6 3 0.11831745041717746
6 4 0.095249252844662
7 5 0.0775689213010483
7 6 0.06253347894360309
sum = 0.7395009381114036
Устранена ошибка, когда, при подсчете вер-тей 7-5 и 7-6, в возможные комбинации попадали цепочки содержащие недопустимые результаты (из принятых условий задачи). Такие как 6-0, 6-1, 2-6 и т.д. так как в этих точках игра бы прекратилась. На основе решения от @MBo, получился такой код:
def tennis_test(p, x, wins, looses, wi=0, lo=0, prob=1.0):
if wi == wins and lo == looses:
return prob
res = 0.0
if (wi < wins) and ((wi >= 6 and wi - lo < 2) or (wi < 6)) and ((lo >= 6 and lo - wi < 2) or (lo < 6)):
res += tennis_test(p + x*(1-p), x, wins, looses, wi+1, lo, prob*p)
if (lo < looses) and ((wi >= 6 and wi - lo < 2) or (wi < 6)) and ((lo >= 6 and lo - wi < 2) or (lo < 6)):
res += tennis_test(p - p*x, x, wins, looses, wi, lo+1, prob*(1-p))
return res