跳转至

两个孩子问题

题

一个家庭有两个孩子,每个孩子独立地以 \(\frac12\) 为男孩、以 \(\frac17\) 生在一周的某一天。分别在下面三种已知条件下,求两个都是男孩的概率:

  1. 至少有一个是男孩。
  2. 老大是男孩。
  3. 至少有一个是周二出生的男孩。

一句话

\(1/3\)、\(1/2\)、\(13/27\)——三个答案都对,差别全在条件事件是什么。真正决定答案的是信息怎么到你手里的:同一句"我有个男孩",按不同机制说出口,答案可以是 \(1/3\) 也可以是 \(1/2\)。

关键技巧

按长幼把家庭写成有序对,样本空间 \(\{BB, BG, GB, GG\}\) 等可能。条件概率就是在条件事件里数 \(BB\) 的占比:

  • 至少一个男孩:条件事件 \(\{BB, BG, GB\}\),\(BB\) 占 \(\frac13\)。
  • 老大是男孩:条件事件 \(\{BB, BG\}\),\(BB\) 占 \(\frac12\)。"老大"把男孩钉在一个具体位置上,另一个孩子就是一枚独立的新硬币。

"至少一个"之所以偏离 \(\frac12\),是因为它没指定是哪个孩子——\(BB\) 家庭有两个男孩可以满足条件,却只被数了一次,而 \(BG\)、\(GB\) 各算一次。

抽样机制才是题面的真身。 "至少一个男孩"对应的机制是:筛选——从所有两孩家庭里挑出有男孩的,再问。若换成"家长随手挑一个孩子,告诉你他的性别",听到"男孩"时:\(BB\) 家庭必然说男孩,\(BG\)/\(GB\) 家庭只有一半概率说男孩,贝叶斯一算

\[ P(BB \mid \text{听到男孩}) = \frac{\frac14 \cdot 1}{\frac14 \cdot 1 + \frac12 \cdot \frac12} = \frac12 \]

同一句话,两种机制,两个答案。

解

第三问把每个孩子细分成 14 种(性别 × 星期),两个孩子共 \(14^2 = 196\) 种等可能。

  • 含"周二男孩"的家庭:老大是周二男孩 14 种,老二是周二男孩 14 种,两个都是重复算了 1 种,共 \(14 + 14 - 1 = 27\) 种。
  • 其中两个都是男孩:老大周二男孩、老二任意男孩 7 种,反过来 7 种,重复 1 种,共 \(7 + 7 - 1 = 13\) 种。
\[ P(BB \mid \text{至少一个周二男孩}) = \frac{13}{27} \approx 0.481 \]

为什么一个"周二"能把 \(\frac13\) 拉向 \(\frac12\)?\(BB\) 家庭有两次机会拥有周二男孩,\(BG\) 家庭只有一次——"周二"这个细节几乎把男孩钉在了某个具体孩子身上,重复计数的那 1 种越不显眼,答案越接近第二问。

一般地,若男孩带有一个概率为 \(p\) 的特征(周二 \(p = \frac17\),生日某天 \(p = \frac{1}{365}\)):

\[ P(BB \mid \text{至少一个带特征的男孩}) = \frac{2p - p^2}{4p - p^2} = \frac{2 - p}{4 - p} \]

\(p = 1\) 回到 \(\frac13\),\(p \to 0\) 趋于 \(\frac12\);\(p = \frac{1}{365}\) 时是 \(\frac{729}{1459} \approx 0.4997\)。

延伸

  • 周二版本同样怕机制:若家长随机挑一个孩子,说出他的性别和生日星期,听到"周二出生的男孩",答案回到 \(\frac12\)。\(\frac{13}{27}\) 只在"筛选出至少有一个周二男孩的家庭"这个机制下成立。
  • 判断机制的一个问法:如果真相是 \(BG\),对方有没有可能说出"女孩"?有可能(随机挑孩子报性别)——答案 \(\frac12\);不可能(问卷问"你有儿子吗",只统计回答"有"的)——答案 \(\frac13\)。
  • 现实里的"独立等概"并不成立:男女出生比约 \(1.05 : 1\),同胞性别也有轻微相关。题目是在理想模型下讲条件概率,别拿它推断真实人口。
  • 和三门问题同一个坑:三门问题 里主持人怎么选门决定换门胜率是 \(\frac23\) 还是 \(\frac12\),这里家长怎么选孩子开口决定答案是 \(\frac13\) 还是 \(\frac12\)。条件概率题的第一步永远是写清楚:观察到的事件是被什么过程生成的。
  • 常见错误:把"至少一个男孩"当成"某个孩子是男孩",于是答 \(\frac12\);或者用 \(\{BB, BG, GG\}\) 三种无序组合当等可能样本空间——\(BG\) 其实有两种排列,概率是 \(BB\) 的两倍。
数值验证

按 (性别, 星期) 全枚举 196 个有序家庭,分别按"筛选"和"随机挑一个孩子开口"两种机制算:

from fractions import Fraction as F
from itertools import product

kid = [(s, d) for s in "BG" for d in range(7)]           # 14 种等可能,d=2 记作周二
fam = list(product(kid, repeat=2))                       # 196 个有序家庭(老大, 老二)
P = F(1, len(fam))
both = lambda f: f[0][0] == f[1][0] == "B"

def filtered(cond):                                      # 机制一:筛出满足条件的家庭
    return sum(P for f in fam if both(f) and cond(f)) / sum(P for f in fam if cond(f))

print(filtered(lambda f: any(k[0] == "B" for k in f)))   # 1/3   至少一个男孩
print(filtered(lambda f: f[0][0] == "B"))                # 1/2   老大是男孩
print(filtered(lambda f: ("B", 2) in f))                 # 13/27 至少一个周二男孩

def told(pred):                                          # 机制二:随机挑一个孩子如实报告
    num = den = F(0)
    for f in fam:
        for k in f:                                      # 每个孩子被挑中的概率 1/2
            if pred(k):
                den += P / 2
                num += P / 2 * both(f)
    return num / den
print(told(lambda k: k[0] == "B"), told(lambda k: k == ("B", 2)))   # 1/2 1/2

def trait(p):                                            # 男孩带概率 p 的特征,按类型加权枚举
    types = {"B+": p / 2, "B-": (1 - p) / 2, "G": F(1, 2)}
    num = den = F(0)
    for a, b in product(types, repeat=2):
        w = types[a] * types[b]
        if "B+" in (a, b):
            den += w
            num += w * (a[0] == b[0] == "B")
    return num / den
for p in (F(1), F(1, 7), F(1, 365)):
    print(p, trait(p), trait(p) == (2 - p) / (4 - p))    # 1 1/3 True | 1/7 13/27 True | 1/365 729/1459 True