java - 我如何证明该算法给出了在办公桌抽屉中找到欧元的正确概率?
问题描述
作业
在你的办公室里有一张桌子,有 50% 的机会持有一欧元。这张桌子有三个抽屉。如果这张桌子上有一个欧元,它同样可能在其中一个抽屉里。如果你已经在第一和第二个抽屉里徒劳地寻找欧元,那么它在第三个抽屉里的概率是多少?
解决方案:
int iterations = 10000;
int desk;// 0 or 1 - 50%
int[] foundEuro = new int[5];
for (int i=1; i <= iterations; i++){
desk = (int) (Math.random() * 2);
if ( desk == 0){ // found Euro
int drawer = (int) (Math.random() * 3);
if ( drawer == 0){
foundEuro[drawer]++; // euro in drawer1
} else {
foundEuro[drawer]++; // euro in drawer2
foundEuro[drawer+1]++; // euro in drawer3
}
} else {
foundEuro[desk]++;
}
}
showResult(foundEuro);
float probability = ( ((float) foundEuro[0]) / iterations) * 100;
System.out.printf("%.2f%%", probability);
抽屉 1 中的输出
欧元:抽屉 2 中的 1638
欧元:抽屉 3 中的 6622
欧元:3343
16,38%
注意
我认为,我的代码没有错误,应该显示正确的结果,但如果它真的是正确的概率因为在第三个抽屉里找到欧元,而在前两个抽屉里却没有。
解决方案
你的算法和结果是完全错误的。您计算的基本上是硬币在桌子上给定抽屉中的概率,这显然是 1/2 * 1/3,正确桌子的概率 * 正确抽屉的概率 = 1/6 大约 16.6
然而,正确答案是25%。您可以在纸上解决这个问题,或者您可以调整您的程序以正确反映“如果您已经在第一个和第二个中徒劳地搜索它”约束。您基本上必须丢弃那些违反此约束的随机硬币选择。然后代码变为:
int iterations = 100000;
int found = 0;
int violateThePrecondition = 0;
for (int i = 1; i <= iterations; i++) {
int desk = (int) (Math.random() * 2);
if (desk == 0) { // found Euro
int drawer = (int) (Math.random() * 3);
if (drawer == 2) { // coin in drawer 2
found++;
} else { // drawers 0 and 1 can by definition not have the coin
violateThePrecondition++;
}
}
}
float probability = (((float) found) / (iterations - violateThePrecondition)) * 100;
System.out.printf("%.2f%%", probability);
25.05%
对代码的最小更改是将概率计算更改为
float probability = ( ((float) foundEuro[0]) / (iterations - foundEuro[2])) * 100;
所涉及的数学是(cNdM 是桌子 M 的抽屉 N 中的硬币 = 1/3 * 1/2 = 1/6,d0 是桌子 0 中的硬币 = 1/2):
P(c2d0 | !c1d0 and !c0d0) =
P(c2d0 and (!c1d0 and !c0d0)) / P(!c1d0 and !c0d0) =
with (!c1d0 and !c0d0) = (!d0 or c2d0)
P(c2d0 and (!d0 or c2d0)) / P(!d0 or c2d0) =
P(c2d0) / (P(!d0) + P(c2d0)) =
1/6 / (1/2 + 1/6) =
1/6 / 4/6 =
1 / 4
推荐阅读
- r - ggplot2中多面填充条形图中的标签百分比
- html - 如何为第一个元素上下文分配默认值?
- python - 如何复制用户的文本?
- javascript - ContentControl 操作减慢 Word Online
- sql - 可配置报表插件,sql查询
- openshift - OpenShift CronJob 可以从 ImageStream 中受益吗?
- c# - 使用 Newtonsoft 反序列化只有 getter 的抽象类
- c++ - 为什么 c++ 模板在被多个源文件包含时不会生成重复的符号?
- reactjs - 在组件中映射道具时如何为道具的孩子编写排除项?
- java - 如何使用 FileDialog 读取文件的数据?