Last active
December 26, 2018 08:28
-
-
Save zombie110year/d5f9b9c863cb2b5daea2f10d6e2ac960 to your computer and use it in GitHub Desktop.
用 Python 模拟三门问题求解
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /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