写在前面
现在的技术岗位面试中,大部分公司都会问概率相关的问题。比如互联网公司的研发工程师,算法工程师,算法研究员,数据分析师,以数据驱动为核心的公司的风控/营销相关的岗位等等。特别是算法工程师和数据分析师,如果工龄较短或者是校招,几乎是必考。
此专栏将持续更新概率计算问题及解答。对于每道题,首先给出个人的思路参考,从概率论的角度推公式求解,然后用蒙特卡洛模拟的方式来验证结果。
这是概率面试题连载第 4 期,本期我们看一个最近朋友在面试中遇到的问题。
往期的内容整理在 这篇文章 里;或者看这个 github 仓库。
问题描述
A,B,C 三个人比赛,A赢B的概率是0.4,A赢C的概率是0.6,B赢C的概率是0.8。不存在和棋。
现在他们打大循环(两两之间均有一场比赛,每人两场)决出冠军,如果出现三个人均赢一盘棋的情况,则加赛一轮大循环,直到决出冠军
求: A 最终胜出的概率
思路参考
记 Pab 为 ab 之间的比赛 a 获胜的概率,Pac 为 ac 之间的比赛 a 获胜的概率,Pbc 为 bc 之间的比赛 b 获胜的概率
两两之间均有一场比赛,一共有三场比赛。每场比赛有两种结果,三场比赛共有 8 种结果。
这 8 种结果中,A 在 AB 之间的比赛和 A 在 AC 之间的比赛均获胜时,A 夺冠,占 8 种比赛结果中的两种,概率为 Pab * Pac
。
当 A 在 AB 之间的比赛获胜、C 在 AC 之间的比赛获胜、B 在 BC 之间的比赛获胜时,需要重新进行大循环赛,占 8 中比赛结果中的 1 种,概率为 Pab * (1 - Pac) * Pbc
。
当 B 在 AB 之间的比赛获胜、A 在 AC 之间的比赛获胜、C 在 BC 之间的比赛获胜时,需要重新进行大循环赛,占 8 中比赛结果中的 1 种,概率为 (1 - Pab) * Pac * (1 - Pbc)
。
其余的 4 中比赛结果为 A 未夺冠。
记循环赛后 A 夺冠的概率为 P
求的答案
蒙特卡洛模拟
import numpy as np
Pab = 0.4
Pac = 0.6
Pbc = 0.8
def round():
ab = ac = bc = 0
if np.random.rand() >= Pab:
ab = 1
if np.random.rand() >= Pac:
ac = 1
if np.random.rand() >= Pbc:
bc = 1
if ab == 1 and ac == 0 and bc == 1:
return round()
if ab == 0 and ac == 1 and bc == 0:
return round()
if ab == 1 and ac == 1:
return 1
else:
return 0
T = int(1e5)
for i in range(10):
na = 0
for t in range(T):
na += round()
print("P(a win): {:.4f}".format(na / T))
模拟结果
P(a win): 0.2997
P(a win): 0.2989
P(a win): 0.2999
P(a win): 0.2987
P(a win): 0.3007
P(a win): 0.3010
P(a win): 0.2991
P(a win): 0.2995
P(a win): 0.2975
P(a win): 0.3002
这里介绍一下目前正在连载的书《Fifty challenging problems in probability with solutions》,这书比较老,第一版是 1965 年出版的,但是很经典,流传至今仍然是概率题面试的重要读物之一。
本书的特点是全面而基础,一共有 56 道题,覆盖初等概率论中的重要话题,例如条件概率,全概率,期望的定义,条件期望,随机游走等。书中给出的解法强调使用初等方法,只有很少数的题涉及到微积分。点击下面直接获取
【书籍】Fifty Challenging Problems in Probability with Solutions