问题
如下图所示,有三个箱子A、B和C。每个箱子有2个球,编号分别为1,2,3,4,5,6。其中1,2,3为红色,4,5,6为蓝色。现随机从一个箱子中抽取出一个球,如果这个球是红色,则另一个球也是红色的概率是多少?
大多数人错误的分析理解
这道题目做错的人非常多,大多数人在分析这个问题的时候,认为答案应该是1/2。因为第一个抽中是红球,这表示2个蓝球的箱子可以被排除了。这样只有红+红和红+蓝,这样最终的答案应该是50%。结果是不是这样呢?我们先用蒙特卡罗法进行10000次实验看下结果。实现代码附在文章尾。
结果与解读
第一次抽中紅球的次数: 5014
另一个也是红球的次数: 3323
两个都是红球的概率为: 66.3%
在以上的结果中,实验共10000次,其中第1次就抽中红球的次数为5014次,约50%。由于红球蓝球各一半,所以结果符合预期。在这5000次中,2个都是红球的次数为3323次,所以概率为 3323/5514 = 66.3%,即约为 2/3。
错误原因分析
根据实验结果,答案显然不是1/2,而是2/3。实验结果与大部分人的预期不一致,说明之前的预期是错误的。而错误的原因在于,抽中小球的概率为3种情况,而不是2种。即,实际可能抽中1,2,3三种球。其中,1和2号球抽中时,另一个球也是红色。所以答案是 2/3 。这里有争议的地方就是1和2号球被第一次选中的情况很多人为理解成为一种情况,因此得出结论总共只有2种情况,有1种满足条件,所以答案是1/2。这里我们再追加一个箱子有2个红球,即:
这时,显然,另一个箱子是红色的机率会增加,答案为 5/6。如果我们再追加大量的红+红的箱子,使红+红箱子数为n个, 红+蓝1个,蓝+蓝1个,则答案为 (2n+1)/(2n+2),这就是说当红+红的箱子总数很大时,另一个箱子的机率几乎是肯定的。所以,原题目的答案为 2/3 是正确的。
Java实现
/**
* 在本实现中,每个箱子用一个长度为2的字符串表示。
* 每位表示一个球,其值为R或B,分别表示红球或蓝球。
*/
public class BallProblems {
public static void main(String[] args) {
String[] boxes = { "RB", "RR", "BB" };
int totalTimes = 10000; // 总测试次数
int oneRedTimes = 0; // 有1个红球的次数
int twoRedTimes = 0; // 有2个红球的次数
// 进行 totalTimes 次测试。
for (int i = 0; i < totalTimes; i++) {
// 随机选择的一个箱子
String box = boxes[(int) (Math.random() * 3)];
// 选中一个箱子的球是否为红色
Boolean isRed = box.charAt((int) (Math.random() * 2)) == 'R';
// 如果是红,则继续判断另一个是否也是红色
if (isRed) {
// 选中红色的次数加1
oneRedTimes++;
// 另一个也是红色,则表示两个都是红色
if (box.equals("RR"))
// 两个都是红球的次数加1
twoRedTimes++;
}
}
System.out.printf("第一次抽中紅球的次数: %d\n另一个也是红球的次数: %d\n两个都是红球的概率为:%4.1f%%\n",
oneRedTimes, twoRedTimes, 1.0 * twoRedTimes / oneRedTimes * 100);
}
}