Skip to content

Instantly share code, notes, and snippets.

@zombie110year
Last active December 26, 2018 08:28
Show Gist options
  • Select an option

  • Save zombie110year/d5f9b9c863cb2b5daea2f10d6e2ac960 to your computer and use it in GitHub Desktop.

Select an option

Save zombie110year/d5f9b9c863cb2b5daea2f10d6e2ac960 to your computer and use it in GitHub Desktop.
用 Python 模拟三门问题求解
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
"""
三门问题
数学上的解释:
此问题中有两个动作, 它们先后发生: A: "从 0,1,2 号门中随机选择一个", B: "主持人打开一扇门"
因此, 可以用以下事件组成的集合作为该随机试验的全集:
1. A_0: "选择 0 号门"
#. A_1: "选择 1 号门"
#. A_2: "选择 2 号门"
#. B_0: "主持人打开 0 号门"
#. B_1: "主持人打开 1 号门"
#. B_2: "主持人打开 2 号门"
#. True: "得到汽车"
#. False: "未得到汽车"
假设 2 号门中为汽车, 且第一次选择的概率都相等.
.. math:: P(A_0) = P(A_1) = P(A_2) = \frac{1}{3}
用矩阵表示为
.. math:: P(A) = \begin{bmatrix}
\frac{1}{3} \\ \frac{1}{3} \\ \frac{1}{3}
\end{bmatrix}
主持人的选择受到第一次选手选择的影响, 事件 B_k 的概率可以如此表示:
.. math:: P(B|A) = \begin{bmatrix}
0 & 1 & 0 \\
1 & 0 & 0 \\
0.5 & 0.5 & 0 \\
\end{bmatrix}
当选择不换门, 得到随机变量的分布为:
.. math:: P{不换} = P(B|A)P(A) = \begin{bmatrix}
\frac{1}{3} \\ \frac{1}{3} \\ \frac{1}{3}
\end{bmatrix}
得到汽车的概率为 :math:`\frac{1}{3}`
当选择换门, 则选手只能选择唯一剩下的那扇门, 选中的概率有
.. math:: P{选中} = P(B_0|A_1)P(A_1) + P(B_1|A_0)P(A_0) + 0 = \frac{2}{3}
"""
from random import choice as 随机选择
门中之物 = (False, False, True);
# False 代表山羊, True 代表汽车
门之索引 = [0, 1, 2];
欺人以方 = {
0: 1,
1: 0,
2: 随机选择((0, 1))
}
def 落定生根():
起手之择 = 随机选择(门之索引)
return 门中之物[起手之择]
def 随机而动():
起手之择 = 随机选择(门之索引)
主持之欺 = 欺人以方[起手之择]
副之索引 = 门之索引.copy()
副之索引.remove(起手之择)
副之索引.remove(主持之欺)
变通之择 = 副之索引[0]
return 门中之物[变通之择]
def main(num):
定动总和 = 0
定之正解 = 0
动之正解 = 0
for i in range(int(num)):
定动总和 += 1
if 落定生根():
定之正解 += 1
if 随机而动():
动之正解 += 1
print("定: {:0>.2f}, 动: {:0>.2f}".format(定之正解/定动总和, 动之正解/定动总和))
if __name__ == "__main__":
main(1e6)
# 算一百万次 耗时大概 5 秒
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment