分赌注问题

问题背景

​ 水平相同的两个赌徒A,B,约定先胜t局的人赢得赌注,在赌博的某时刻,两赌徒终止赌博,此时A胜r局,B胜s局,应如何分配赌注?

​ 这个问题通常称为点数问题,是嗜好赌博的法国学者梅雷于1654年向数学家帕斯卡提出的。为此帕斯卡和法国数学家费马于1654年7月到10月之间进行了一系列通信讨论赌注分配问题,成为了概率论的起源

​ 当荷兰数学家惠更斯到巴黎时,听说费马和帕斯卡在研究赌注问题,他也进行了研究,并在1657年撰写了《论赌博问题中的计算》一书,提出数学期望,推动了概率论的发展。

​ 1713年,瑞士数学家伯努利的《猜度术》一书的面世,标示着概率论已成为数学的一个重要分支。

假设

  • 显然赌注最少会在t-max(r,s)局结束,因为r,s相对大小不影响问题分析的结构,所以不妨假设r>s
  • 依据获胜概率来分赌注,即若记两人分别取得最后胜利的概率为$P_A$, $P_B$ ,且$P_A$ +$P_B$ = 1,则两人应按照$P_A : P_B$的比例分赌注。
  • 没有人作弊,故假设两个人分别每一次博弈获胜的概率均为0.5,且博弈相互独立。
事件 事件说明
t 获得奖金最少需要获胜的次数
r A已经获胜的次数
s B已经获胜的次数
i 比赛结束时的比赛次数
$P_A$ A先获胜t局的概率
$P_B$ B先获胜t局的概率
$P_a$ A获胜一局的概率
$P_b$ B获胜一局的概率
M 总奖金数

问题分析

显然,最少t-r局结束,最多2*t-r-s-1局结束所以 $i\in [t-r,2t-r-s-1)$

设第i场博弈后,A获胜$P{A(i)}=C{i-1}^{t-r-1} P_a^{t-r-1}P_b^{i-1-(t-r-1)} *P_a$

将$Pa=P_b=0.5$带入化简得:$P{A(i)}=0.5^iC{i-1}^{t-r-1}$ 对其求和$P_A=\sum{i=t-r}^{2t-r-s-1}P_{A(i)}$,

假设A,B每一局获胜概率相同,先赢得18局的人赢得赌注,并假设A胜10局且B胜7局的时候终止赌博,则有:

计算得P~A理论值~=0.7596588134765625,故A应拿走$M * P_A$的奖金,B拿走剩下的奖金

不妨设产生随机数为1则认为单局赌博A获胜,以A获胜频率/仿真次数视为概率可得仿真结果如下表

仿真次数 100 1000 1万 10万
A获胜频率 0.74 0.75 0.7633 0.76064

代码

计算理论值概论代码

#-*- coding:utf-8 -*-
# @Author : Dummerfu
# @Contact : https://github.com/dummerchen
# @Time : 2020/12/20 12:35
import numpy as np
from scipy.special import perm,comb
t=18
r=10
s=7
def P_a(x):
s1=pow(0.5,x)
s2=comb(x-1,t-r-1)
print('s1:%lf s2:%lf' %(s1,s2))
return s1*s2
if __name__ == "__main__":
P_A=0
for i in range(t-r,2*t-r-s):
print('i:' ,i)
P_A=P_A+P_a(i)
print(P_A)

仿真代码

#-*- coding:utf-8 -*-
# @Author : Dummerfu
# @Contact : https://github.com/dummerchen
# @Time : 2020/12/20 12:55
import matplotlib as mpl
import numpy as np
from matplotlib import pyplot as plt

mpl.rcParams['font.sans-serif'] = 'SimHei'
mpl.rcParams['axes.unicode_minus'] = False

t=18
r=10
s=7

if __name__ == "__main__":
Echo=[100,1000,10000,100000,1000000]
for echo in Echo:
print('echo:',echo)
tot_A=0
tot_B=0
for i in range(echo):
tempr=r
temps=s
for j in range(0,2*t-r-s+20):
rad=np.random.randint(0,2)
if rad==1:
tempr+=1
else:
temps+=1
if tempr==t:
tot_A+=1
break
if temps==t:
tot_B+=1
break
print('tot_A:%d tot_B:%d P_A:%lf P_B:%lf' %(tot_A,tot_B,tot_A/echo,tot_B/echo))