Python不用学,看看你就懂;拿来就能用,用用你就会
无需安装编程软件,把代码拷贝到在线编辑器即可运行
三门问题(Monty Hall problem)来自一档美国的电视游戏节目。节目主持人(Monty Hall)邀请嘉宾挑战一道有奖竞猜题目:有三扇门,其中一个门后面有奖品汽车,先请嘉宾选一个(但不打开),然后主持人打开剩下两个门中的一个,是没有车的。现在主持人问嘉宾:要不要改变主意,换选另一扇仍然关着的门?
问题是:嘉宾换选或是不换,对他的获奖成功率有影响吗?
直觉是没有,当然没有影响!怎么会有影响呢?
所以当玛丽莲·沃斯·莎凡特博士在她专栏《Ask Marilyn》的回答是**改选会更有优势**时,在美国引起了激烈的争议:人们寄来了数千封抱怨信,很多寄信人是科学老师或学者。一位来自佛罗里达大学的读者写道:“这个国家已经有够多的数学文盲了,我们不想再有个世界上智商最高的人来充数!真让人羞愧!” 另一个人写道:“我看你就是那只山羊!” 美国陆军研究所的埃弗雷特·哈曼写道,“如果连博士都要出错,我看这个国家马上要陷入严重的麻烦了。”
但她是对的!这位玛丽莲女士10岁时智商测试就得到228分,看来不是白给的。
理论方面我们这里就不讲了,不换的成功率是1/3,换的成功率是2/3,自己可以去研究概率论或是网上查一查。我们只是想用程序来验证一下这个结果。
以下就是我们的程序,第一部分还是先验证一下不换的成功率,然后在第二部分严格重现换选的情景并算出成功率:
import random
获奖次数_不换 = 0 # 不换而获奖的计数器
获奖次数_换 = 0 # 换而获奖的计数器
试验次数 = 100000 # 换和不换各做这么多次实验
for i in range(试验次数): # 不换的实验
door_list = ["A","B","C"] # 三扇门的编号
car = random.choice(door_list) # 汽车随机放在某扇门后
bet = random.choice(door_list) # 挑战者随机选择一扇门
if bet == car: # 不换!直接揭晓答案
获奖次数_不换 = 获奖次数_不换 + 1
for i in range(试验次数): # 换的实验
door_list = ["A","B","C"] # 三扇门的编号
car = random.choice(door_list) # 汽车随机放在某扇门后
bet = random.choice(door_list) # 挑战者随机选择一扇门
# 现在主持人随机选择一扇门予以排除
# 这扇门不是挑战者选择的门,也不是汽车所在的门
host_list = ["A","B","C"]
host_list.remove(bet)
if car in host_list:
host_list.remove(car)
discard = random.choice(host_list)
# 现在挑战者决定换,即换成剩下的一扇门,看看是否获奖
door_list.remove(bet) # 去掉自己已经选过的门
door_list.remove(discard) # 去掉主持人排除的门
bet = door_list[0] # 只剩下一扇门,换成它!
if bet == car: # 换!揭晓答案
获奖次数_换 = 获奖次数_换 + 1
print("不换的获奖概率:", 获奖次数_不换/试验次数)
print("换的获奖概率: ", 获奖次数_换/试验次数)
我们分别做10万次实验,看看计算结果如何:
不换的获奖概率: 0.3315
换的获奖概率: 0.66885
看起来我们的玛丽莲女士确实是对的,不必再表示困惑了。
这里是《简单又好玩的Python》栏目,我们的口号是“Python不用学,用用你就会”。欢迎关注!
源代码文件地址:
根据评论补充一下。如果不换的实验也要严格模拟的话,完整的代码应该是这样的:
for i in range(试验次数): # 不换的实验
door_list = ["A","B","C"] # 三扇门的编号
car = random.choice(door_list) # 汽车随机放在某扇门后
bet = random.choice(door_list) # 挑战者随机选择一扇门
# 现在主持人随机选择一扇门予以排除
# 这扇门不是挑战者选择的门,也不是汽车所在的门
host_list = ["A","B","C"]
host_list.remove(bet)
if car in host_list:
host_list.remove(car)
discard = random.choice(host_list)
if bet == car: # 不换!揭晓答案
获奖次数_不换 = 获奖次数_不换 + 1
模拟结果还是1/3左右。
如果仔细观察,就会发现这里中间的主持人那一段,对后面的获奖次数的计算毫无影响,从编写代码的角度看是多余的,所以这是我在正文中没有包括这段代码的原因。从这个意义上说,会编程的人脑子里只要用编程的思路稍微转一下,就知道不换的中奖率肯定是保持不变的,自然也不会认同“换不换中奖率都是50%”的部分直观派观点。