[概率论]MontyHall问题(三门问题)&蒙特卡洛初步

参考链接1参考链接2

MontyHall问题

问题描述如下:

1
2
3
参赛者面前有三扇关闭着的门,其中一扇的后面是一辆汽车,选中后面有车的那扇门就可以赢得该汽车,
而另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,主持人会开启剩
下两扇门中的一扇,露出其中一只山羊。主持人其后会问参赛者要不要更换选择,选另一扇仍然关着的门。

首先给出结论:更换的话选到车的概率是2/3,不更换选中车的概率是1/3。用python代码模拟:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import random

def initDoor():
door=[]
carid=random.randint(1,3)
for i in range(0,3):
if i == (carid-1):
door.insert(i,"car")
else:
door.insert(i,"goat")
return door

def hostchoose(doorid,playerchoice,carid):
doorid.remove(carid)
if playerchoice == carid:
hostchoice = random.choice(doorid)
else:
doorid.remove(playerchoice)
hostchoice = doorid[0]
return hostchoice


def play(choice,change,door):
doorid=[1,2,3]
dooridd=doorid.copy()

carid = door.index("car")+1
hostchoice = hostchoose(doorid,choice,carid)

if change == 1:
dooridd.remove(hostchoice)
dooridd.remove(choice)
newchoice = dooridd[0]
else:
newchoice = choice

if newchoice == carid:
return 1
else:
return 0

if __name__=="__main__":
win = 0
for i in range(10000):
door = initDoor()
choice = random.randint(1,3)
win = win + play(choice,0,door)
print(win)

运行结果与上面的结论相符合。
借鉴了文章开头的两个参考链接,对此结论有如下解释:

穷举出所有可能情况,假设玩家选择1号门,那么主持人就要从2、3号门中打开有🐏的门,车在1、2、3号门中等可能:

情况 1号门 2号门 3号门 不换
1 car goat goat
2 goat car goat
3 goat goat car

可见改变选择选中车的概率是2/3;不改变选择,选中车的概率是1/3。
从上表可以逆向思考:如果刚开始选到车,更换选择后必选不到;如果开始没有选到车,更换选择后必选到。所以更换选择后选到车的概率其实就是刚开始没有选到车的概率,即为2/3。

网上争来争去(包括这个问题刚刚出来时有很多类似的争论),归根到底还是:为什么从剩下的两扇门中选中车的概率不是1/2?换言之,假设在主持人打开一扇“羊门”后,找一个对之前发生的事都不知情的路人在剩下的两扇门中选择,显然选中车的概率是1/2,并不是2/3。这就是蒙特霍尔悖论。问题出在哪里呢?
我认为,无论是之前的玩家,还是后来找来的路人,虽然它们看上去都是要在两个门中做出选择,但事实上两者进行的并不是同一个实验——因为两者掌握的信息并不对等。后者不必分析,显然是fifty fifty;对于前者,一开始选到车的概率是1/3,主持人打开“羊门”并不会改变这个概率(即选到车与主持人开门两个事件是相互独立的)。
仍然假设玩家选择一号门,不妨设事件A:车在一号门后面。事件B:主持人选到“羊门”。则显然有P(A)=1/3,P(B)=1,并且A、B相互独立,则由独立事件性质
$$
P(A|B)=P(A)=1/3
$$
即不改变选择选到车的概率仍是1/3。类似的问题还有很多,举一个极端情况,例如100 0000张彩票有1张有奖,你选择一张后,去掉剩余彩票中的99 9998张无奖彩票,问是否换成另外一张,答案显然是更换,此时你中奖概率高达0.999999,显然不是1/2。

蒙特卡洛初步

蒙特卡洛方法是一种基于“随机数”的计算方法,以求Π为例。考虑边长为2(图中是1)的正方形的内切圆

随机抛一点下去,落入内切圆中的概率显然是
$$
P=\frac{\pi}{4}
$$
所以
$$
\pi =4P
$$
只要求得P即可,可用python模拟随机落点的行为计算:

1
2
3
4
5
6
7
8
9
10
11
12
13
import random

def calPi(count):
k = 0
for i in range(count):
x = random.uniform(-1,1)
y = random.uniform(-1,1)
if x**2+y**2<1:
k=k+1
return float(4*k/count)

if __name__=="__main__":
print(calPi(10000000))

模拟1000 0000次的结果是3.14194。

0%