生日悖论
在算法导论书上看到个比较有意思的概率算法,在这里加上自己的理解分享下:
上次刚看同学发的朋友圈说道:“两个人同一间宿舍,而且同年同月同日生,这个缘分真的是醉了”,当时我也是醉醉的,看了这个算法后才发现,屋里有23个人,那么就可以50%的概率生日是一样的。
是这样子证明的:
首先,假设屋子里有K个人,分别对他们编号1,2,3….k号。不考虑闰年的情况,那么一年就有n=365天,首先还是要假设生日是均匀分布在一年的n天中(喜欢在春天生就都在春天生这就不均匀了),然后还要假设两个人生日相互独立(什么双胞胎那些还用得着算么),
那么两个人同一天(具体的一天)生日的概率就1/n2 (生日的概率是1/n,两个人同一天生日当然就相乘了~),那么两个人同一天生日(365天随便一天)的概率就是1/n (n个1/n2相加)
也就是说假如屋里面有两个人,那么他们同一天生日的概率是1/365,那现在要解决的问题是,屋里要有多少人,才能使这个概率上升到1/2 ?
用事件的对立面来求,假设事件P={ 屋里至少两个人生日一样},Q={ 屋里每个人生日都不一样},那么P=1-Q
那么知道Q的概率就能知道P的概率了,设BK为前K个人的生日都有一样,Ai为前第i个人与前i-1一个人的生日都不一样,那么就可以得到递推式子
Bk=Bk-1^Ak
它的等价形式为
P{Bk}=P{Bk-1}P{ Ak | Bk-1}
应用递归式可以得到P{Bk}=P{B1} P{ A2 | B1} P{ A3 | B2}… P{ Ak-1 | Bk-2} P{ Ak | Bk-1}
=1*(n-1/n) (n-2/n)… (n-k+1/n)(B1是规定为1的,然后P{ A2 | B1}就是365中有一天已经给B1用了,那么就剩下n-1天了,所以概率为(n-1/n))
P{Bk}=1*(1-1/n) (1-2/n)… (1-k-1/n)
然后已知 1+x<=ex(两个都是单调增函数,取0时为相等,过了就ex 大了,高中学的嘿嘿)
那么有1*( ) ( )… ( )<=(e-1/n)(e-2/n)…(e-(k-1/n))= (e-k(k-1)/2n))<=1/2
求得当n=365时,必有k>=23,所以结论是至少有23个人在一间屋子里,那么至少有两个人生日相同的概率至少是1/2。
在程序中,有时可能考虑产生n个随机数,比如产生1000个范围为0到1亿之间的随机数,任意两个随机数都不重复的概率为多大?传统计算方法无法计算过于大的位数,下面是一个近似解:
1 /* 2 * 功能:范围为r的k个随机数互不相同的概率(r>k)。 3 * 若k>=r,显然概率为0. 4 * 例1:50个人中生日互不相同的概率为distinct(365,50)约为0.0296。 5 * 例2:随机产生名称为Integer.MAX_VALUE以内整数做文件名的文件1万个,没有相同文件名的概率为distinct(Integer.MAX_VALUE, 10000)约为0.977 6 * 7 */ 8 package com.copy; 9 import static Java.lang.Math.*; 10 public class Distinct { 11 12 13 public static void main(String[] args) { 14 15 System.out.println(distinct(Integer.MAX_VALUE ,10000)); 16 } 17 18