反直觉的一个游戏 - 三门问题 (Monty Hall problem)

三门问题,也叫蒙提霍尔问题(Monty Hall Problem)

以电视节目 - Let‘s make a deal的主持人蒙提霍命名的一个反直觉问题。

游戏简介

假设有3个门。 其中一个后面藏着宝藏,其余2个都是空门(美国节目中1个后面有汽车,其余的2个是山羊)。

游戏开始:

首先你先选择一张门,

选好后,主持人帮你在其余2扇没有被选择的门中打开一扇没奖的门。

这时候你有一个选择权, 换门还是不换门?

直觉上换不换几率都是50%,那到底几率是多少? 换是不是得奖的机会大一些?

可以用代码来模拟一遍。python

编程就是一步一步来,当然有时候要想清楚直接到达想要到的地方。

第一遍我们就用一步步来的方法走一遍吧。 (代码一部分借鉴了哈佛的CS109)

首先我们先定义下 有3扇门,其中奖品在某一扇门中。

首先安装下 numpy库

1.这个可以用 random.randint来实现。 randint(start, end, size) 随机选择的3个门中间的一个

1 def simulate_prizedoor(nsim):
2     return np.random.randint(0, 3, (nsim))

2.然后我们可以定义下,一开始选择的一扇门。 这里可以用固定选择法,也可以用随机法,数据大的情况下差别不大。这里我们直接用了固定选择第一扇门(0)

1 def simulate_guess(nsim):
2     return np.zeros(nsim, dtype=np.int)

3.然后我们 模拟主持人,开一扇没有奖品的门。

1 def goat_door(prizedoors, guesses):
2     result = np.random.randint(0, 3, prizedoors.size)
3     while True:
4         bad = (result == prizedoors) | (result == guesses)
5         if not bad.any():
6             return result
7         result[bad] = np.random.randint(0, 3, bad.sum())

这里要实现的逻辑是, 先生成一个0到2的随机数。 然后匹配直到 不等于 我们一开始的选择的那扇门 或 宝藏存在的那扇门。

4.然后模拟,我们假如我们在主持人打开门之后, 选择换一张门。

1 def switch_guess(guesses, goatdoors):
2     result = np.random.randint(0, 3, guesses.size)
3     while True:
4         bad = (result == guesses) | (result == goatdoors)
5         if not bad.any():
6             return result
7         result[bad] = np.random.randint(0, 3, bad.sum())

看得出来实现的代码和上面是一样的。 我们换的这扇门,不能是原来那扇,而且也不能是开了的那扇。

5.计算胜率。

1 def win_percentage(guesses, prizedoors):
2     return 100 * (guesses == prizedoors).mean()

这里需要注意, 如果单纯的bool type的数据是没有mean这个函数的。 np 把真假转换成了1,0这样才可以计算平均数。mean = 总值/数组的总数

6.最后我们就可以测试下,换和不换的区别了。 因为大数定律,我们测试100000遍

 1 pd = simulate_prizedoor(nsim)
 2 guess = simulate_guess(nsim)
 3 goats = goat_door(pd, guess)
 4 guess = switch_guess(guess, goats)
 5
 6 nsim = 100000
 7
 8 print "Win percentage when keeping original door"
 9 print win_percentage(simulate_prizedoor(nsim), simulate_guess(nsim))
10
11 print "Win percentage when switching doors"
12 print win_percentage(pd, guess).mean()
Win percentage when keeping original door
33.32
Win percentage when switching doors
66.69

测试结果, 胜率方面 换能提高1倍的胜率。 (2个数相加超过100是因为小数点后的换算原因。)

测试完如果有点不能接受,我们换种方式

————————————————————————————一百遍的分割线——————————————————————————————————————

一切都不变的情况下,假如说有100扇门,你先选一扇,主持人帮你开98扇, 这时候也只剩下了2扇门。 你是换呢,还是不换。

这个代码实现就有点小区别了。 因为大家熟悉了之前的实现方法, 我就换了一种实现方法。

1. 定义100扇门中有1个宝箱,这个做太多改变, 再定义我们随机选择了一扇门(之前是固定)

1 start = 0
2 end = 100
3 def simulate_prizedoor(nsim):
4     return np.random.randint(start, end, (nsim))
5
6 def simulate_guess(nsim):
7     return np.random.randint(start, end, (nsim))

2. 这里我们的主持人要关98扇门,真正要实现这个这个模拟,需要各种循环和条件。 其实根本没必要那么麻烦, 实现一个程序或者过程只要目的达到了就OK,不管是不是一模一样的模拟了一遍。  编程就是要跳出盒子,什么事都在盒子里面,永远无法做到效率的解决问题。

实现逻辑: 这里面不管主持人开多少门, 最后只会留2扇门。 这2扇门只有2种可能性:以猜中没猜中为逻辑

1. 我们猜中了, 所以我们猜的门 和 另外一扇随机留下的门

2. 我们猜错了,所以留下一扇我们猜的门,和一扇宝藏门。

实现这个代码很简单。

1 def guess_switch(guess_keep, pd):
2     alter = np.random.choice([x for x in range(start,end) if ((x != guess_keep)&(x != pd)).any()])
3     num = np.where(guess_keep == pd,alter,pd)
4     return num

3. 胜率计算

 1 def win_percentage(guesses, prizedoors):
 2     return 100*(guesses == prizedoors).mean()
 3
 4 nsim = 10000
 5
 6 pd = simulate_prizedoor(nsim)
 7 guess_keep = simulate_guess(nsim)
 8 guess_sh = guess_switch(guess_keep, pd)
 9
10 #keep guesses
11 print "Win percentage when keeping original door"
12 print win_percentage(pd, guess_keep)
13
14 #switch
15 print "Win percentage when switching doors"
16 print win_percentage(pd, guess_sh)
Win percentage when keeping original door
1.04
Win percentage when switching doors
98.96

数据胜于雄辩。  

PS:本人代码水平有限, 请大家多多指正。 另外一个问题, 有没有可能实现所有的if都用np.where来替代。  if和for真是效率太低了。
时间: 2025-01-14 01:16:30

反直觉的一个游戏 - 三门问题 (Monty Hall problem)的相关文章

Monty Hall 问题与贝叶斯定理的理解

 三门问题(Monty Hall problem),是一个源自博弈论的数学游戏问题,大致出自美国的电视游戏节目Let's Make a Deal.问题的名字来自该节目的主持人蒙提·霍尔(Monty Hall). 游戏规则 游戏参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门就可以赢得该汽车,而另外两扇门后面则各藏有一只山羊.当参赛者选定了一扇门,但未去开启它的时候,节目主持人会开启剩下两扇门的其中一扇,露出其中一只山羊.主持人其后会问参赛者要不要换另一扇仍然关上的门.问

The Monty Hall Problem-蒙特霍问题

//The Monty Hall Problem #include <iostream> #include <cstdlib> // Needed for random numbers using namespace std; // ==================== //     main function // ==================== int main() {   int i;   int numWinsStay = 0;   int numWinsSw

模式中的反直觉概率

我们先从一个看起来简单的问题说起: 假设有一枚均匀的硬币,用 H表示正面,T表示反面.反复地抛掷这枚硬币会得到一个由 H 和 T 组成的随机序列.问题是:平均需要掷多少次硬币,才能得到 THTHT 这个模式? 比如说掷硬币的结果是 HTTHTHT,那么总共用了 7 次才得到 THTHT 这个模式.而如果结果是 THHTTHTHT,则总共用了 9 次. 一个令人惊讶的事情是,同样长度的两个模式,它们的首次出现时间的期望是可以不同的.在这个问题中,答案是平均需要掷 42 次才能得到 THTHT 这个

一个游戏程序员的学习资料

三维图形学: 搞三维图形学首先还是要扎扎实实的先看解析几何.线性代数.计算几何的教材,后面的习题一个都不能少.国内数学书还是蛮好的.苏步青大师的<计算几何>称得上具有世界级水准,可惜中国CAD的宏图被盗版给击垮了.现在是我们接过接力棒的时候了.It’s time! <Computer Graphics Geometrical Tools> <计算机图形学几何工具算法详解>算法很多,纰漏处也不少. <3D Math Primer for Graphics and G

一个游戏中的条件概率问题

假设你在进行一个游戏节目.现给三扇门供你选择:其中一扇门后面是一个大奖(比如奥迪R8),另两扇门后面神马都没有.你不是托,所以你的目的当然是拿大奖,但是你显然不知道门后面是啥东东.主持人(虽然ta知道门后面都是啥,但ta就是不告诉你)先让你做第一次选择.在你选择了一扇门后,主持人并没有立刻打开这扇门,而是打开了另外一扇木有奖的门给你看.现在,主持人告诉你,你有一次重新选择的机会.那么,请你思考一下,你是坚持第一次的选择不变,还是改变第一次的选择?哪种做法更有可能中大奖? 这个问题貌似很简单:主持

创业的时候只能专心致志做好一件事。什么叫“一件事”?只能开发一个游戏,只能做一个产品

著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:王统伟链接:http://www.zhihu.com/question/19550531/answer/15183706来源:知乎 这是我在商界招商网看到天使投资人曾李青(原腾讯公司五位创始人之一)对早期创业公司的看法 ,觉得对你蛮有帮助的,你可以参考下!曾李青:早期创业公司九种死法第一,跨行业创业 比如原来做游戏的人要做电商,原来做互联网社区的要做游戏.现在的互联网环境下,这种跨行业创业失败概率都会比较高. 在演讲中,他

三年一个人使用虚幻引擎(UDK)开发的一个游戏心路

三年一个人使用虚幻引擎(UDK)开发的一个游戏心路 转载   出处来源http://mobile.51cto.com/news-488590.htm 对于我个人来说,完成她的意义不仅在与完成了一个儿时的愿望,也是一次战胜自我的旅程,3年的时光,经历了种种变荡.最终,通过压榨自己的业余时光,学习新语言,新游戏平台,3D建模,3D动画,美工,音效,FLASH,各种配置. 作者:来源:CocoaChina|2015-08-18 09:57 收藏 分享 这个游戏没有做任何宣传(这个帖子算是第一个吧),其

使用CocosSharp制作一个游戏 - CocosSharp中文教程

注:本教程翻译自官方<Walkthrough - Building a game with CocosSharp>,官方教程有很多地方说的不够详细,或者代码不全,导致无法继续,本人在看了GoneBananas项目代码后,对本教程进行了部分修改,但当前只涉及Android方面,iOS因没有环境验证代码,暂未修改. 本人博客地址:http://fengyu.name 原文链接:http://fengyu.name/?cat=game&id=295 相关资源: 离线PDF文档:Downloa

如何在cocos2d-x中使用ECS(实体-组件-系统)架构方法开发一个游戏?

引言 在我的博客中,我曾经翻译了几篇关于ECS的文章.这些文章都是来自于Game Development网站.如果你对这个架构方式还不是很了解的话,欢迎阅读理解 组件-实体-系统和实现 组件-实体-系统. 我发现这个架构方式,是在浏览GameDev上的文章的时候了解到的.很久以前,就知道了有这么个架构方法,只是一直没有机会自己实践下.这一次,我就抽空,根据网上对ECS系统的讨论,采用了一种实现方法,来实现一个. 我很喜欢做游戏,所以同样的,还是用游戏实例来实践这个架构方法.我将会采用cocos2