用程序消除一道概率题的二义性
无意在维基看到了一个关于概率悖论的讨论Boy or Girl paradox。有争议的的题目如下:
史密斯先生有两个孩子,至少其中之一是男孩,请问两个孩子都是男孩的可能性有多大?
原文如下:
Mr. Smith has two children. At least one of them is a boy. What is the probability that both children are boys?
一部分人的答案是1/3,一部分人的答案是1/2.为什么会产生这样的结果呢,文中说得很清楚是因为问题本身存在歧义,对“至少一个孩子是男孩”的信息做不同的假设,导致了不同的结果。问题归根结底是由于自然语言的二义性,将问题转化成了两个不同的数学模型,从而产生了两个不同的结果。我们知道设计一种编程语言的任务之一就是消除其二义性,因此一般而言编程语言是一种没有歧义的语言(所以程序员都喜欢写代码不喜欢说话么),如果用编程语言来描述这一问题,会不会好理解点呢?以java为例,我们来看看。
以下是对史密斯先生有两个孩子的可能情况进行描述,其中random.nextBoolean()函数随机返回true或false的概率均为1/2,用于模拟现实中生男孩女孩的概率各一半。可见程序不仅描述了所有的组合,还明确了题目中暗含的条件。
class TwoChildren{Child child1;Child child2;public TwoChildren()//一个孩子是男孩或女孩的概率是50%{child1 = random.nextBoolean()?Child.BOY:Child.GIRL;child2 = random.nextBoolean()?Child.BOY:Child.GIRL;}}
接着描述“至少一个孩子是男孩”,因为这里是存在歧义的地方,所以转化成代码描述时,我们会根据两个不同的假定,得到不同的代码。1/3结果的假定条件:观察了史密斯的两个孩子,其中一个是男孩:
boolean isObserved(TwoChildren draw)
{return draw.child1 == Child.BOY || draw.child2 == Child.BOY;
}
熟悉java的程序员会注意到,如果child1为BOY的话,child2不会被观察(||运算符后面的代码不会被执行),是否和自然语言描述不一样?我们从逻辑或运算定义可知二者是等价的,即使||运算符后面的代码被执行,也不影响程序结果,换成自然语言就是我们观察史密斯的两个孩子时,一个一个的观察,如果发现其中一个是男孩,就已经保证了“至少一个是男孩”,就没必要接着观察了。
接着描述1/2的结果假定条件:随机观察了史密斯的一个孩子,其中一个是男孩:
boolean isObserved(TwoChildren draw)
{return random.nextBoolean()?draw.child1 == Child.BOY:draw.child2 == Child.BOY;
}
其中random.nextBoolean()函数随机返回true或false的概率均为1/2,就是两个孩子被选中观察的概率是1/2.
最后我们描述问题的提出
if(isObserved(draw))
{observedCount ++;if(draw.child1 == Child.BOY && draw.child2 == Child.BOY){//两个孩子都是男孩matchedCount++;//经过很多次运算后,((double)matchedCount/observedCount)最可能的值是多少?}
}
至此我们将一个以自然语言描述的问题,转化成了一个以程序语言描述的问题。这个转化是否正确呢,我们做10万次测试,看结果是否满足数学推导的预期。以下是一个完整的测试代码:
package hermitdl.test2;import java.util.Random;/*** Test for <<Boy or Girl paradox>>*/
public class App
{static enum Child{BOY,GIRL};static Random random = new Random();static class TwoChildren{Child child1;Child child2;public TwoChildren()//一个孩子是男孩或女孩的概率是50%{child1 = random.nextBoolean()?Child.BOY:Child.GIRL;child2 = random.nextBoolean()?Child.BOY:Child.GIRL;}}//随机检查一个孩子的性别是否是男孩static class PeekOneTest extends ProbabilityTest{@Overrideboolean isObserved(TwoChildren draw) {return random.nextBoolean()?draw.child1 == Child.BOY:draw.child2 == Child.BOY;}}//检查两个孩子的性别,是否其中之一是男孩static class PeekTwoTest extends ProbabilityTest{@Overrideboolean isObserved(TwoChildren draw) {return draw.child1 == Child.BOY || draw.child2 == Child.BOY;}}static abstract class ProbabilityTest{int observedCount = 0;int matchedCount = 0;//在isObserved为真的情况下计数,以及两个孩子均是女孩的情况计数。void test(TwoChildren draw){if(isObserved(draw)){observedCount ++;if(draw.child1 == Child.BOY && draw.child2 == Child.BOY){两个孩子都是男孩matchedCount++;}}}abstract boolean isObserved(TwoChildren draw);void printResult(){System.out.printf(this.getClass().getSimpleName() +"=%d/%d=%f\n",matchedCount,observedCount,((double)matchedCount/observedCount));}}public static void main( String[] args ){PeekOneTest peekOneTest = new PeekOneTest();PeekTwoTest peekTwoTest = new PeekTwoTest();TwoChildren draw;for(int i = 0;i < 1000000; i++){draw = new TwoChildren();peekOneTest.test(draw);peekTwoTest.test(draw);}peekOneTest.printResult();peekTwoTest.printResult();}
}
以下为程序的几次运行结果:
PeekOneTest=249436/499301=0.499570
PeekTwoTest=249436/750234=0.332478
PeekOneTest=250209/500229=0.500189
PeekTwoTest=250209/749846=0.333681
PeekOneTest=249963/500234=0.499692
PeekTwoTest=249963/749712=0.333412
可见模拟结果始终分别在1/2与1/3附近波动,是符合数学预期的。
用程序消除一道概率题的二义性相关推荐
- 一道概率题引发对考研数学复习的思考
一道概率题引发对考研数学复习的思考 知识回顾 如题,今天上午我兴致勃勃地拿出2006年数学一做了起来.做前面还算顺利,直到最后那道概率题,关于极大似然估计的题目,我的内心:艹了,这怎么跟之前做的不一样 ...
- 使用程序解决一道逻辑推理题
今天看朋友发了一个老问题,一道很有意思的推理题:(转载请指明出于breaksoftware的csdn博客) 小明和小强都是张老师的学生,张老师的生日是M月N日,2人都知道张老师的生日是下列10组中的一 ...
- 一道概率题:重男轻女的情况下家庭女孩数量的问题
2014.3.29阿里巴巴实习生招聘笔试题上出了这样一道选择题: 某国家非常重男轻女,一个家庭如果生了一个女孩,便要再生一个,直到生下男孩为止,假设生男生女概率一样,则平均每户人家有几个女孩? 显然这 ...
- 时间流逝(flow)——概率题
时间流逝(flow) Time Limits: 1s Memory Limits: 256MB Description 生活可以很简单.可以探索水底世界的神秘,也可以去发现奇特新生物,亦或踏上一段新生 ...
- (组合数学习题)递推关系一道经典题分析与解答
文章目录 题目 分析与解答 求解 程序实现(C++) 题目 来看下面一道题,主要用到的是组合数学中的递推关系部分的内容. 某长度为nnn的二进制序列,要求其中至少有连续的333个000出现,问:能产生 ...
- 计算机软件水平考试分类程序员,历年计算机软件水平考试程序员部分真题
试题1 A.为了提高计算机的处理机和外部投备的利用率, 把多个程序同时放入主存储崐器,在宏观上并行运行. B.把一个程序划分成若干个可同时执行的程序模块的设计方法. C.多个用户在中端设备上以交互方式 ...
- 基于2022高考数学全国卷I概率题解题思路初步分析新冠病毒疫苗
基于2022高考数学全国卷I概率题解题思路初步分析新冠病毒疫苗 1. 2022高考数学全国卷I概率题 2. 卡方(χ2\chi^2χ2)检验原理回顾 3. 解答2022高考数学全国卷I概率题 4. 上 ...
- 2009年9月刊《程序员》算法题之我见——思索之一
本系列文章目录 2009年9月刊<程序员>算法题之我见--思索之一 2009年9月刊<程序员>算法题之我见--思索之二 2009年9月刊<程序员>算法题之我见--思 ...
- 程序员考试下午题知识点总结
程序员考试下午题知识点总结 第一大题:程序框图 程序流程图又称程序框图,是用统一规定的标准符号描述程序运行具体步骤的图形表示.程序框图的设计是在处理流程图的基础上,通过对输入输出数据和处理过程的详细分 ...
最新文章
- java反射 获取参数名_java
- AngularJS---核心特性
- html textarea换行和dom换行
- python基础入门: for 循环
- Https 加密原理分析
- arcgis导出access数据库能打开的文件
- .net面试题(会持续更新)
- C++中的Overload、Override和Overwrite
- 算法:平衡二叉树110. Balanced Binary Tree
- 《Bible》各版本
- 小型矢量图标于前端页面如何应用
- 黑金AX7Z100 FPGA开发板移植LWIP库(二)PL端
- ubuntu下CHM阅读器
- Jwt入门教程:实战( 三) | 使用Springboot基于拦截器和redis的Jwt判断用户登录以及安全校验
- android网易云播放时图片,Android 网易云音乐图片高斯模糊
- native react 图片多选_N-第三方-react-native-image-picker,选择图片上传
- 百度终于要出手了?文心一言
- 苹果不创新,库克有道理
- sqoop导入数据到hive
- 如何锁定 input 内容不可修改
热门文章
- python个人博客搭建说明书_技术分享|利用Python Django一步步搭建个人博客(二)...
- 刘知远、赵鑫、施柏鑫:AI青年科研人员成长之路
- SAP PM 初级系列1 – 定义维护工厂和维护计划工厂
- SAP SD基础知识之组织架构设计-Shipping Point篇
- SAP SD基础知识之交货单不完全日志
- 正则化方法:L1和L2 regularization、数据集扩增、dropout
- 「机器学习速成」训练神经网络:反向传播、梯度爆炸消失Dropout
- 法国科学家发布AI模型,阐释蛋白结构和功能及进化关系
- 监督学习和无监督学习
- 前沿丨人工智能的框架战争:FB继续挑战Google