julia编程 生日问题概率计算 班级有人和你生日重复的概率,
2021-06-09 本文已影响0人
mudssky
班级里面遇上生日生日和你重复的人,你可能直觉上觉得生日重复是个小概率事件,实际上生日重复这个事件在一个班级里面发生的概率还是相当高的,一个50人的班级,存在生日重复的概率就高达97%,一个40人的班级,存在生日重复的概率高达87%
但是你之前的想法其实也并没有问题
生日重复发生在你身上的概率就没有那么高了,在一个60人的班级里面,存在和你生日重复的人的概率约为15%,50人班级是12.6%,40人班级是10%
首先我们需要用julia编写一个计算排列数的方法
"""
计算排列数 A_n^m,输入需要是整数类型,返回值是BigInt类型,因为排列数很容易变成大数
"""
function A(m::Integer, n::Integer)
# basic param check
if n == 0 || m == 0
throw(ArgumentError("n or m should not be zero or negative"))
elseif n < m
throw(ArgumentError("n should be lager than m"))
end
function A_inner(m, n)
if (m<=1)
return n
end
return A_inner(m-1, n - 1) * n
end
return A_inner(BigInt(m), BigInt(n))
end
班级所有人生日不重复的概率
我们假设生日的概率是符合古典概型的。实际上因为生孩子会有扎堆现象,所以现实中生日重复的概率应该是比这个计算要高的
根据古典概型每个可能性是等概率的,我们只要把生日不相同的总数和所有可能的总数相除就是最终的概率
所有人生日不重复的概率计算公式如下,n为班级人数
忽略了2月29日出生的小孩,简化计算。假设算的是没有2月29的年份
下面是julia中的实现
function birthdayProblem(studentNum)
# 一年大约有365个日期,因为2月29日4年出生条件有点难,直接忽略了
return A(studentNum,365)/BigInt(365)^studentNum
end
# 计算班级人数为1到60时,每个人的生日不同的概率
birthdayList=birthdayProblem.(1:60)
birthdayDupP = map(x->1-x,birthdayList)
然后我们进行绘图
using Plots
plotly()
plot(birthdayList,ylim=(0,1),labels="birthday no dup")
plot!(birthdayDupP,ylim=(0,1),labels="birthday dup")
结果如下
image-20210609112957568.png班级有人和你生日重复的概率
反着想,没有人和你生日重复就很好理解了.
假设班级有n人,你的生日已经确定了,那么只有n-1个人要选,他们每人都可以选择剩下的364天.
总可能数是他们每人选择全部的365天
也就是下式
julia 代码如下
function birthdayHasNoSame(studentNum)
studentNum=studentNum-1
# 先让别人选,然后你只能选跟别人不一样的
return BigInt(364)^studentNum/BigInt(365)^studentNum
end
我们计算相反的,也就是和你生日重复的列表并绘图,结果如下
birthdayHasNoSamePlist=birthdayHasNoSame.(1:60)
plot(map(x->1-x,birthdayHasNoSamePlist),ylim=(0,0.2))
image-20210609113542928.png
如果在现实中,如果你出生的月份比较热门,这个概率会更高一些.