这个版本的代码有点乱,已更新Python代码,也许看起来好一些
链接 张宇/王式安 考研数学 概率论争议题 【Python版】
一、原题题目
本题为1987年实考题
设两箱内装有同种零件,第一箱装50件,其中有10 件一等品,
第二箱装30件,其中有18件一等品,先从两箱中任挑一箱,
再从此箱中前后不放回任取两个零件,求:
(1)先取出的零件是一等品的概率p.
(2)在先取出的是一等品的条件下,后取的仍是一等品的条件概率q.
1. 争议
如果你看到这篇文章,估计已经知道争议,在此简单介绍即可。
张宇和王式安第一问答案一样,无争议,为0.4。
第二问,张宇认为,应该用条件概率公式,答案约为0.4855.
但出题人王式安先生认为,应用全概率公式,答案为0.3849.
2. 结论
本题思想简单,题目中也无明显歧义,简单重复验证即可。
个人觉得,应该是王式安先生错了,错误的原因在于忽略了“第一次取的是一等品”这一事件已经发生。
(应考虑贝叶斯,执果索因)
但我去年跟的王式安,概率论部分考得还行,虽然理解的不够深入,但是我确实会做。
能在培训界混口饭吃还是有点东西的,如果有跟王式安的朋友看到了不要慌,老王可以,
跟着他走,考研问题不大。
二、代码实现
【闲话】
本来是打算用C++写的,奈何重装系统之后安装的DEV CPP不太顺手,调试的时候老是出问题。
我离开它一段时间,它就再也回不来了。
顺手拿Java撸了一个,由于撸的时候刚刚从C/C++转换过来,思维混乱,敬请谅解。(主要是因为我不太会Java,也没有对象。
这个Java代码能用,要充分感谢科技的进步,感谢技术标准的提升,感谢编译器的优化。
这个代码可能存在许多问题,如有发现还请指正。
import java.util.*;
public class Test01 {
static final int INFERIOR=0;
static final int GOOD=1;
static boolean[]status=new boolean [50];
static int AboxInfer=(50-10);
static int BboxInfer=(30-18);
static int firstCount=0;//第一次为正品的次数
static int successCount=0,failtureCount=0;//第一次为正品&&第二次为正品 的次数 与 失败次数
static int examCount=100000;//实验次数
public static void reStatus() {
for(int i=0;i<status.length;++i) {
status[i]=false;
}
}
public static void distribute(int []box,int countInferoir) {
int count=0;
while(count<countInferoir) {
Random random = new Random();
int tempCount=random.nextInt(box.length);
//System.out.println(tempCount);
if(tempCount>=0&&tempCount<box.length&&(!status[tempCount])) {
//没生成过这个数+边界检查
status[tempCount]=true;
box[tempCount]= INFERIOR;
++count;
continue;
}
}
}
public static void cheek(int []box) {
int count=0;
char boxOrder='B';
if(box.length>30) {
boxOrder='A';
}
System.out.print(boxOrder+"箱中的次品位置为: ");
for(int i=0;i<box.length;++i) {
if(box[i]==INFERIOR) {
++count;
System.out.print(i+" ");
}
}
System.out.println(boxOrder+"箱中共有"+count+"个次品");
}
public static void fetch(int []box) {
//Java里面这种情况应该也是传“地址”吧...瑟瑟发抖
Random random3 = new Random();
int tempCount=random3.nextInt(box.length);
if(tempCount>=0&&tempCount<box.length&&(!status[tempCount])) {
status[tempCount]=true;//校验状态 模拟不放回
if(box[tempCount]==GOOD) {//第一件正品
++ firstCount;
int tempCount2=random3.nextInt(box.length);
while(status[tempCount2]) {
//如果该数生成过了 则循环生成
tempCount2=random3.nextInt(box.length);
}
if(box[tempCount2]==GOOD) {
//第二件也是正品
//成功
++successCount;
reStatus();
return;
}
else {
++failtureCount;
reStatus();
return;
}
}
else {
++failtureCount;
reStatus();
return;
}
}
else {
System.out.println("看到这个你代码有问题");
reStatus();
return;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello word!");
//初始化两个数组
//A 10/50
//B 18/30
int []Abox=new int [50];
int []Bbox=new int [30];
//两个箱子初始化问题,写出来清楚些
//按题意,实际上令前xx个产品为次品仍可,但为了模拟随机性,随机分配次品
//Java中Random()不分配种子时,会以time做种子,随机性满足需要
for(int i=0;i<50;++i) {
Abox[i]=GOOD;
}
for(int i=0;i<30;++i) {
Bbox[i]=GOOD;
}
//true代表数已生成
//重置状态数组
reStatus();
distribute(Abox,AboxInfer);
reStatus();
distribute(Bbox,BboxInfer);
reStatus();
cheek(Abox);
cheek(Bbox);
/*
两箱产品初始化完成
以下部分为抽样检查阶段
*/
System.out.println("本次实验共测试"+examCount+"次。 ");
//抽取过程
int tempCount=examCount;
int countA = 0,countB =0;
while(tempCount>0) {
--tempCount;
Random random2 = new Random();
int chooseCount=random2.nextInt(2);//0 A 1 B
if(chooseCount==0) {
fetch(Abox);
++countA;
}
else if(chooseCount==1) {
fetch(Bbox);
++countB;
}
}
//抽取完成
System.out.println("选到A箱"+countA+"次");System.out.println("选到B箱"+countB+"次");
System.out.println("其中,第一次取到正品的次数为"+firstCount+",失败次数为"+failtureCount+",概率为"+(double)firstCount/examCount);
System.out.println("其中,第一次取到正品的条件下,第二次仍然取到正品的次数为"+successCount+", 概率为"+(double)successCount/firstCount);
}
}
Hello word!
A箱中的次品位置为: 0 1 2 3 4 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 23 24 25 26 27 28 29 31 33 34 35 37 38 39 40 41 42 44 45 49 A箱中共有40个次品
B箱中的次品位置为: 1 3 7 9 10 11 14 16 19 20 25 28 B箱中共有12个次品
本次实验共测试100000次。
选到A箱50090次
选到B箱49910次
其中,第一次取到正品的次数为39883,失败次数为80580,概率为0.39883
其中,第一次取到正品的条件下,第二次仍然取到正品的次数为19420, 概率为0.48692425344131585
我们可以看到,更倾向于张宇/汤家风的答案。