You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何证明该算法能正确计算抽屉欧元的目标条件概率?

概率问题验证:前两个抽屉无欧元时第三个抽屉的概率

问题背景

办公室内有一张桌子,存在欧元的概率为50%;该桌子有3个抽屉,若桌子内有欧元,则欧元等概率分布在任一抽屉中。问题:若已在前两个抽屉中未找到欧元,欧元在第三个抽屉中的概率是多少?

你的代码与运行输出

代码片段

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){ // 桌子内有欧元
  int drawer = (int) (Math.random() * 3);
  if ( drawer == 0){
   foundEuro[drawer]++; // 欧元在抽屉1
  } else {
   foundEuro[drawer]++; // 欧元在抽屉2
   foundEuro[drawer+1]++; // 欧元在抽屉3
  }
 } else {
  foundEuro[desk]++;
 }
}
showResult(foundEuro);
float probability = ( ((float) foundEuro[0]) / iterations) * 100;
System.out.printf("%.2f%%", probability);

运行输出

Euro in drawer 1: 1638
Euro in drawer 2: 6622
Euro in drawer 3: 3343
16,38%

你的疑问

我认为代码无错误,应能输出正确结果,但不确定该结果是否为“前两个抽屉未找到时欧元在第三个抽屉”的正确概率,如何证明该算法给出的概率正确?


首先得说,你的代码逻辑存在几个关键错误,导致输出结果完全不符合问题要求。咱们先拆解问题核心:我们要算的是「在前两个抽屉都没找到欧元」这个前提下,「第三个抽屉有欧元」的条件概率,而你的代码既没正确模拟这个前提,也没正确统计符合条件的样本。

代码里的问题点

  1. 变量逻辑混乱:你用desk=0表示桌子有欧元,desk=1表示没有,但桌子没有欧元时,所有抽屉都空,根本不应该给foundEuro[desk]计数——这完全是无意义的操作,会打乱统计结果。
  2. 抽屉计数错误:当桌子有欧元时,你在drawer!=0的分支里同时给两个抽屉的计数加1,这相当于把欧元同时放在了两个抽屉里,完全违背了“欧元只在一个抽屉”的设定。
  3. 没筛选条件样本:问题要求只看「前两个抽屉没欧元」的情况,但你的代码用了所有迭代次数做分母,完全忽略了条件概率的核心——只统计符合前提的样本。

用数学推导证明正确概率(贝叶斯定理)

咱们用贝叶斯定理来算正确结果,这样就能明确标准:

  • 设事件A:桌子里有欧元,P(A)=0.5
  • 事件B:前两个抽屉都没有欧元
  • 我们要算的是:P(第三个抽屉有欧元 | B)

步骤1:计算P(B)(前两个抽屉都空的总概率)

P(B) = P(B|A)*P(A) + P(B|¬A)*P(¬A)

  • P(B|A):桌子有欧元时,前两个抽屉都空的概率 = 1/3(只有欧元在第三个抽屉时,前两个才空)
  • P(B|¬A):桌子没有欧元时,前两个抽屉都空的概率 = 1
    所以P(B) = (1/3)0.5 + 10.5 = 2/3

步骤2:计算条件概率

我们要求的是「前两个抽屉空,且第三个有欧元」的概率,除以「前两个抽屉空」的概率:
分子:P(第三个抽屉有欧元且B) = P(A)P(欧元在第三个抽屉) = 0.5(1/3) = 1/6
最终概率 = (1/6) / (2/3) = 1/4 = 25%

修正后的模拟代码(验证正确结果)

我们需要严格模拟问题场景:只统计「前两个抽屉空」的样本,再在这些样本里数「第三个抽屉有欧元」的次数:

int iterations = 100000;
int totalValidCases = 0; // 前两个抽屉都没找到欧元的总次数
int euroInThirdDrawer = 0; // 符合前提且第三个抽屉有欧元的次数

for (int i = 0; i < iterations; i++) {
    // 50%概率桌子有欧元
    boolean hasEuro = Math.random() < 0.5;
    int euroDrawer = -1; // -1代表桌子没有欧元
    if (hasEuro) {
        // 欧元等概率在三个抽屉(0=抽屉1,1=抽屉2,2=抽屉3)
        euroDrawer = (int) (Math.random() * 3);
    }

    // 判断前两个抽屉是否都空:要么桌子没欧元,要么欧元在第三个抽屉
    boolean firstTwoEmpty = (euroDrawer == -1) || (euroDrawer == 2);
    if (firstTwoEmpty) {
        totalValidCases++;
        if (euroDrawer == 2) {
            euroInThirdDrawer++;
        }
    }
}

// 计算条件概率
double probability = ((double) euroInThirdDrawer / totalValidCases) * 100;
System.out.printf("前两个抽屉未找到时,欧元在第三个抽屉的概率:%.2f%%%n", probability);

运行这段代码,结果会稳定在25%左右,和我们的数学推导完全一致。

结论

你的原代码因为逻辑错误,没有正确模拟问题的前提条件,所以输出的16.38%是错误的。通过贝叶斯定理的数学推导,我们可以确定正确概率是25%;而修正后的模拟代码也验证了这个结果,因为它严格遵循了问题要求:只统计符合「前两个抽屉空」的样本,再计算其中第三个抽屉有欧元的比例。

内容的提问来源于stack exchange,提问作者TorbenIT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:52:31