三门问题


问题:三个箱子里只有一个有奖品。你随便选择了一个箱子。在揭晓前,主持人打开了另一个箱子,里面是空的。他问你"换不换?" 换还是不换的中奖率高?
注意:主持人知道哪个箱子里有奖品,他不会打开有奖品的箱子。
答案:换的中奖率是2/3,不换的中奖率是1/3,换。
证明:不换的中奖率显然是1/3,把主持人当空气。1 - 1/3 = 2/3,所以换的中奖率是2/3。上程序模拟:

{2: 33305, 1: 33343, 0: 33352}

0.66575

# -*- coding: gbk -*-
from random import randint
d = {}
n = 100000
def r(): return randint(0, 2)
for i in range(n):
    i = r()
    d[i] = 1 + d.get(i, 0)
print(d) # 看看随机数好使不
cnt = 0
for i in range(n):
    prize_door = r()
    chosen_door = r()
    host_door = r()
    while host_door == prize_door or host_door == chosen_door:
        host_door = r()
    chosen_door = (chosen_door + 1) % 3
    while chosen_door == host_door:
        chosen_door = (chosen_door + 1) % 3
    # prize=0, chosen=0, host=1,chosen=2
    # prize=0, chosen=0, host=2,chosen=1
    # prize=1, chosen=2, host=0,chosen=1
    if chosen_door == prize_door: cnt += 1
print(float(cnt) / n)

坚定信念后开始凑数。以奖品在1为例:

玩家选1 主持人开1 xxx
玩家选1 主持人开2 玩家换成3 不中
玩家选1 主持人开3 玩家换成2 不中
玩家选2 主持人开1 xxx
玩家选2 主持人开2 xxx
玩家选2 主持人开3 玩家换成1 中
玩家选3 主持人开1 xxx
玩家选3 主持人开2 玩家换成1 中
玩家选3 主持人开3 xxx

奖品在2还是3的情况一样。2/4=1/2出来了。主持人一脚踹飞个空箱子,剩下两个箱子里只有一个有奖品。然后玩家可以再选一次,而且可以选和上次一样的(=不换)。

search(诊断试验中的贝叶斯定理:检验阳性就一定患病了吗?)

  天 1 2 3 4 5 6 7 8 9 10
乌云 c c   c   c     c
下雨 r   r r   r r   r

天数=10,乌云数=5,下雨数=6,P(乌云)=0.5,P(下雨)=0.6。乌云and下雨=4 P(乌云,下雨) = 4/5 = 0.8,P(下雨,乌云) = 4/6 = 0.667. 分子一样分母不一样。"下雨天会乌云密布吗?",答案是0.667。大家一般不关心这个,关心的是if 乌云 then 带伞。

乌云and下雨 = 下雨and乌云,注意到这两个事件同时发生了。此处and不是逻辑运算。
if乌云then下雨 != if下雨then乌云,P(if小猫花花不见了then下雨)=1,花花是找龙王去了,还是老寒腿感觉要下雨藏起来了?不说明逻辑原因和结果。我觉得"先验"和"后验"good, "条件"confusing. P(A|B)哪个是条件我又忘了。我们用P(B,A)或P(A,B)呗。

P(乌云)*P(乌云,下雨) = 0.5*0.8 = {0.4=P(乌云&下雨)=0.4} =  P(下雨)* P(下雨,乌云) = 0.6 * 0.667

这么倒腾有啥用?请看"患病"例子。"检验阳性"不是"患病"的原因。P(阳性,患病)是我们关心的,又是未知的。它可以通过已知的P(患病,阳性)和其它概率计算出来。阳性是判断患病的指标之一,还有别的判断方法/指标。检验单为啥不直接印上P(阳性,患病)? 挂号费50,一天看10个病人,一个月1万5,医生要读很多年很难的书。做游戏也不简单,也不是个个挣大钱。

坐飞机时有一个人带炸弹的概率是万分之一。如果我坐时带个炸弹,那么有两个人带炸弹的概率是亿分之一。所以我带个安全得多(当然带而不用)。笑点何在?乘法好像没毛病。我觉得,用计数来计算概率, m/n, m>=30, n>=1000,出来得结果才可信。然而某些论文把n=30叫做大样本。然而研究病/死时,n很大是伦理错误甚至反人类的。然而A国和J国就干了。

search(三门问题 贝叶斯公式),比如

似乎:一个袋子三个球,2个0一个1。不换等价于一次摸到1号球;换等价于摸两次(第一次摸到的不放回)摸到。

# -*- coding: gbk -*-
from random import randint
def r(): return randint(0, 2)
n = 100000; cnt = 0; bag = [0, 0, 1]
for i in range(n):
    j = r(); k = r()
    while k == j: k = r() # 不放回
    if bag[j] or bag[k]: cnt += 1
print(float(cnt) / n)
cnt = 0
for i in range(n):
    j = r(); k = r() # 有时放回,有时不放回。我是写不出对应的计算公式 :-)
    if bag[j] or bag[k]: cnt += 1
print(float(cnt) / n)

闭着眼摸一个放回去,再摸,重复1万次,中奖概率还是1/3。选个箱子后,主持人不开任何箱子光问"换不换",换不换都一样。摸球不放回,3次必定中奖。闭着眼摸一个放回去,主持人替你摸个0号球出来扔掉,睁开眼从里面再摸一个。有可能头一次摸到的1号球放回去后第二次没摸到。

0.5551623333333333 0.33322833333333335
0.5551623333333333 = 5/9
0.33322833333333335 = 1/3

# -*- coding: gbk -*-
from random import randint
def r(): return randint(0, 2)
n = 3000000; cnt = 0; cnt2 = 0; bag = [0, 0, 1]
for i in range(n):
    j = r(); k = r()
    if j == k: cnt2 += 1
    if bag[j] or bag[k]: cnt += 1
prob = float(cnt) / n; prob2 = float(cnt2) / n
print(prob, prob2)
def guess_fraction(x):
    try:
        for i in range(2, 1000):
            for j in range(1, i):
                if abs(float(j) / i - x) < 0.001:
                    print(x, ' = ', j, '/', i, sep='')
                    raise Exception()
    except Exception: pass
guess_fraction(prob); guess_fraction(prob2)