假設今天有一個充滿人的房間,有兩個人的生日日期是相同的機率是多少?
今天房間裡如果有366個人,我們可以非常快速的就知道一定會有兩個人有相同的生日,在這房間裡有相同生日日期的人的機率=1。
那當房間裡有多少人的時候兩個人的生日相同的機率會大於50%呢?當有多少人的時候這機率會甚至大於99%呢?大家不妨先猜一下,真實答案可能和你的猜測大相逕庭唷。因此這才被稱為生日悖論!
先揭曉謎底。
其實只要房間裡有23個人,則兩個人的生日相同的機率就高達50%!
而只要房間裡有60個人,兩人有相同生日日期的機率便會大於99%!
有沒有非常違反你的直覺呢?
是怎麼樣得到這個結果的呢?首先,我們應該以另一個角度切入問題,意即考慮每個人生日都不同的機率是多少。 從這個角度出發,假設房間有N人,N人的生日日期皆不相同的機率(P)會是
而為了計算房間內有至少兩人生日相同的機率,我們只需將1減去P便可得到。這代表我們將所有可能的結果(機率為1)扣除所有人生日皆不相同的狀況(機率為P),扣除後的機率代表的即為至少兩人生日相同的機率(1-P)。
當N=23時,P會小於0.5,因此1-P>0.5,當房間裡有23人時兩個人的生日相同的機率就會大於50%。當N=60時,兩人有相同生日日期的機率便會大於99%!
這是理論上的結果,除此之外,我們也可以用Julia透過蒙地卡羅模擬法估計發生機率。
註:接下來會使用蒙地卡羅模擬法來估計,若對蒙地卡羅模擬法還不熟悉的朋友可以先服用
此篇文章。
Julia程式碼
# 匯入套件StatsBase、Combinatorics、Plots以及PyPlot
using StatsBase, Combinatorics, Plots ; pyplot()
# 自定義一個函數(function)用來計算理論解
# 給定不同n(人數)的情況下,有兩人生日相同的機率
# 使用prod()這個函數,計算括弧內所有值的乘積(從365/365*364/365*…*1/365)即為
# 每人生日皆不同之機率,再用1去減
matchExists(n) = 1 — prod([k/365 for k in 365:-1:365-n+1])
# 自定義一個函數模擬房內有不同人數的情形,且定義方法與matchExists()有些差別。
# 首先,利用rand()隨機(uniform dist.)從1~365產出n個值,代表每個人的生日日期。
# 接著使用counts計算每個數字出現的次數並指派給dayCounts,
# 再來,用maximum()檢查dayCounts裡最大值是否大於1次,即是否有兩人生日相同
# 若是,回傳ture,反之則回傳false
function bdEvent(n)
birthdays = rand(1:365,n)
dayCounts = counts(birthdays, 1:365)
return maximum(dayCounts) > 1
end
# 模擬重複試驗N次,並計算N次中有兩人生日相同的次數,再除以N,得到機率。
probEst(n) = sum([bdEvent(n) for _ in 1:N])/N
# 使用自定義之函數,計算理論上房內有1~60人時兩人有相同生日的機率
xGrid = 1:60
analyticSolution = [matchExists(n) for n in xGrid]
# 使用蒙地卡羅模擬法估計在房內有不同人之情況下,房內有1~60人時兩人有相同生日的機率
N = 10³
mcEstimates = [probEst(n) for n in xGrid]
# 將理論結果與蒙地卡羅模擬法估計出的結果繪製出來比較。
plot(xGrid, analyticSolution, c=:blue, label=”Analytic solution”)
scatter!(xGrid, mcEstimates, c=:red, ms=6, msw=0, shape=:xcross,
label=”MC estimate”, xlims=(0,60), ylims=(0, 1),
xlabel=”Number of people in room”,
ylabel=”Probability of birthday match”,
legend=:topleft)
從圖中可看出估計得非常準確,而當人數超過20時房內有人有相同生日日期的機率已經高達40%了,當房內有超過40人時,有人有相同生日日期之機率則高達90%!
有興趣可以至我的blog參考原文文章:https://www.juliansweb.com/julia-birthday-paradox