期望题
1. 抛一个6面的骰子,连续抛直到6为止,问期望的抛的次数是多少
设期望次数为E,那么有:
[1]1次抛出6的概率为1/6,那么期望次数为1*1/6
[2]本次抛出非6数字的概率为5/6,因为没有抛出6,因此期待抛出6还需要执行试验的次数仍为E,需要注意加上本次(1次)失效的抛掷,即期望次数为(1+E)(5/6)
综合可得:
E = 1*(1/6) + (1+E)(5/6)
解得: E = 6
2. 一个木桶里面有M个白球,每分钟从桶中随机取出一个球涂成红色(无论白或红都涂红)再放回,问将桶中球全部涂红的期望时间是多少?
令E[i]表示木桶里有i个红球时,还需要抽取多少时间可以将所有球都染成红色,对于当前状态下E[i]的计算可以分解为两个部分:
[1] 抽取到的是红球: 需要的时间期望为 i/M * (1+E(i)),其中i/M表示抽取红球的概率,因为抽取到的是红球因此状态没有改变,仍然是E(i)
[2] 抽取到的是白球: 需要的时间期望为 (1-i/M) * (1+E(i+1)),其中(1-i/M)表示抽取到白球的概率,因为抽取到了白球,被涂成红色以后,木桶里将会有i+1个红球,因此状态迁移到 E(i+1)
注意加上当前实验的时间 1
综合可得:
E(i) = i/M *(1+E(i)) + (1-i/M) * (1+E(i+1))
化简可得:
E(i) = E(i+1) + M/(M-i)
显然有: E(M) = 0, 当前桶里M个球都是红色的,不用再做任何抽取操作
(编程时依次从E(M)计算到E(0),返回E(0)即可)
将递归式展开有:E(0) = M/M + M/(M-1) + ... + M/1 + 0
3. 若要使骰子(六个面)的每个数都出现至少一次,那么平均需要掷多少次骰子?即求掷骰子次数的期望
与前一题类似,设掷出第i个数需要抛掷的次数为E(i),i=1,2,3,4,5,6,(需要注意的是第i个数是值之前没有出现过的数字,而不是具体的值)
那么E(i)可由两部分组成:
E(i) = (i/6)(E(i)+1) + (1-i/6)(E(i+1)+1)
[1] (i/6)(E(i)+1) : 已经有i个数字出现了,那么当前抛掷出重复数字的概率为 i/6,状态仍然是E(i),加上当前实验1次
[2] (1-i/6)(E(i+1)+1) : 已经有i个数字出现了,那么当前抛掷出新数字的概率为 1-i/6,状态转移到E(i+1),即当抛掷出了i+1个数字后,仍需要抛掷次数的期望,别忘加当前试验 1 次
E(i) = E(i+1) + 6/(6-i), E(6) = 0
E(0) = 6/6 + 6/(6-1) + ... + 6/1 + 0
4. 你有一把宝剑。每使用一个宝石,有50%的概率会成功让宝剑升一级,50%的概率会失败。如果宝剑的级数大于等于5的话,那么失败会使得宝剑降1级。如果宝剑的级数小于5的话,失败没有效果。问题是:期望用多少个宝石可以让一把1级的宝剑升到9级?
令 E(i) 表示宝剑从 i-1 级升到 i 级需要的宝石个数,对于E(i)有:
对于 i <= 5, 没有失败,因此 E(1) = E(2) = E(3) = E(4) = E(5) = 2
对于 i >= 5, 有:
E(i) = (1/2)*1 + (1/2)*(1 + E(i-1) + E(i))
从i-1级升到i级,
[1] 升级成功,成功概率为 1/2,耗费 1 颗宝石,因此期望的宝石数为:(1/2)*1
[2] 升级失败,失败概率为 1/2,耗费 1 颗宝石,等级降到 i-2级,因此需要从 i - 2 级升到 i-1级,需要E(i-1)次,再从i-1级升到i级需要E(i)次,综上有:(1/2)*(1 + E(i-1) + E(i))
化简得:E(i) = 2 + E(i-1)
E(6) = 2 + E(5) = 2 + 2 = 4
E(7) = 2 + E(6) = 2 + 6 = 6
E(8) = 2 + E(7) = 8
E(9) = 2 + E(8) = 10
那么宝剑从1级升到9级,期望需要的宝石数是: E(2) + ... + E(9) = 36
几个关键概念
以上分析过程涉及到的三个重要概念如下:
1. 伯努利实验
事件E只有两种可能结果:发生和不发生,概率分别为p和(1-p)。E独立重复进行n次可以称为n次伯努利试验。
2. 二项分布
n次伯努利试验发生k次的可能性服从二项分布:
c(n,k) * p^k * (1-p)^(n-k)
3. 几何分布
几何分布有是指以下任一一种情况的离散型概率分布:
[1] 1次成功需要执行伯努利试验的次数X,(X=1,2,3...)
[2] 1次成功之前失败的次数 Y = X-1 =, (Y=0,1,2....).
注意区分以上两种情况,以上两种情况的概率分布为:
[1] P(X=k) = (1-p)(k-1) * p , k = 1,2,... (第k次是第一次成功)
[2] P(X=k) = (1-p)k * p , k = 0,1,2,... (失败了k次以后第一次成功)
以上两种情况下的几何分布的均值和方差:
[1] E(X) = 1/p , D(X) = (1-p)/p2
[2] E(X) = (1-p)/p, D(X) = (1-p)/p2
举例:
一个六面的骰子,平均需要投掷多少次可以掷出数字6:
p = 1/6, 1-p = 5/6
E(X) = 1/p = 6 次
详细可以参考:
https://en.wikipedia.org/wiki/Geometric_distribution
随机数题
关键在于保证各个随机数出现的概率相等。
1. 已知有个rand7()的函数,返回1到7随机自然数,怎样利用这个rand7()构造rand10(),随机1~10。
因为rand7()可以等可能的产生 1~7 之间的数字,因此 (rand7() - 1)等可能随机产生 0~6 的数,那么(rand7() - 1) * 7 + rand7() 可以等可能的产生 1~49 之间的数,因为上式中两个rand7()的组合数是唯一的。
可以将1~49分成 1~40 和 41~49两个区间,选择 1~40这个区间平均划分成10段,每一个分段被随机到的概率相等,每个分段的长度为40/10 = 4,每个分段分别对应1~10。
具体过程为:按公式 (rand7() - 1) * 7 + rand7() 随机一个数,若随机数落入41~49这个区间则丢弃,若随机数落入1~40这个区间,进一步确定分段对应的数值 (x-1)/4 + 1
2. 已知有个randM()的函数,返回1到M随机自然数,怎样利用这个randM()构造randN(),随机1~N。
前一题的推广。分两种情况:
[1] 当 N <= M 时,可以直接使用 randM() 获取随机数,>N的随机数丢弃,<=N 的随机数输出即可。
[2] 当 N > M 时候,需要构造 randM2 = (randM() - 1) * M + randM() 随机 1 ~ M2 的数值,
[3] 如果randM2仍然小于N,那么对 randM2 继续重复[2] 操作,如果randM2大于 N 则停止跳到 [1]
3. 已知一随机发生器,产生0的概率是p,产生1的概率是1-p,现在要你构造一个发生器,使得它产生0和1的概率均为1/2
由题目有:
0 : p
1 : 1-p
连续产生两个数,其组合以及概率如下:
00 : p2
01 : p*(1-p)
10 : (1-p)*p
11 : (1-p)2
可以发现 01 和 10 组合的概率是相等的,只需要将其分别映射到0和1即可。即每次随机产生两个数,如果组合为00或11则丢弃,若为01则映射到1,若为10则映射到0,这样一来产生0和1的概率均为 1/2 。
4. 已知一随机发生器,产生的数字的分布不清楚,现在要你构造一个发生器,使得它产生0和1的概率均为1/2。
使用该随机发生器产生随机数a,b,有以下3种情况:(1)a<b, (2) a == b, (3) a>b,其中情况(1)和(3)是对称的,发生的概率相等,只需要将这两种情况分别映射到0和1即可,其中遇到a==b时忽略。
(也可以找另外一个概率相等的阈值)
**5. 已知一随机发生器,产生0的概率是p,产生1的概率是1-p,构造一个发生器,使得它构造1、2、3的概率均为1/3;…。更一般地,构造一个发生器,使得它构造1、2、3、…n的概率均为1/n。 **
随机等可能的产生n个数,需要构造n个等可能的事件,每一个事件的发生映射到一个数值上即可。
我们可以产生一个由0和1组成的序列,序列中0和1的个数相等,即各出现一半的情况下每种排列出现的概率都是相等的。
随机产生长度为2x的序列,那么0和1各占x个,组合数有 C(2*x, x) >= n ,解出最小的x。对其中的n种等可能情况分别映射到1~n的数字上即可。
6. 给出从n个数中随机选择m个数的方法。n很大,可以认为是亿级别。m可以很小,如接近1;也可以很大,如接近n。
两个有待改进的思路:
(1) 以 1/n 的概率一直重复随机,直到获取了m个数为止
缺陷:[1]难以知道后面随机的数是否与前面的随机数重复,因为数据量很大,不一定能在内存中进行比较。[2] 当m很大时,尤其是无限接近n时,后面产生的数字很多都已经在前面出现过。
(2)每个数字被选中的概率是 m/n,可以遍历所有数字,在遍历的同时以 m/n的概率决定是否选择当前值。当遍历结束时,选择数字的个数在平均意义上来说是m,均值会随着数据量的增大会更好的趋向于m,但值得注意的是该过程仍不能精确的精确到m。
改进后的思路:
遍历第1个数时,选择的概率为 m/n
遍历第2个数时,[1]如果选择了第一个数,则选择的概率为 (m-1)/(n-1);[2] 如果没有选择第1个数,则选择的概率为 m/(n-1)
遍历第i个数时,[1]如果此时已经选择了k个数,那么选择第i个数的概率为 (m-k)/(n-i+1)
这样一来可以保证在剩下的数字中选择适当的数使得总体的数字是m个。对于选择概率 (m-k)/(n-i+1) ,当k=m时概率为0,即所有数字已经选择完毕不再选择,当k=0时,分母会不断减小,以至于概率取向于1。最终得到的结果始终精确到m个数。
7. 给出从n个数中随机选择1个的方法。注意,n非常大,并且一开始不知道其具体值。数字是一个一个给你的,当给完之后,你必须立刻给出随机的结果。
由于n非常大并且需要立即给出答案,因此无法把所有数字都保存起来然后进行随机。
再者n的具体值未知,因此任意时刻都需要有当前的结果。
于是第1个数字肯定选。那么问题就变成了当第i个数字到来时,是保留当前数字还是选择第i个数字的问题,i=2,3,...,n。此过程必须保证截止目前为止所见到的数字被选中的概率都相等。
假设当第i个数字到来时,前i-1个数字被选中的概率相等,此时只需要第i个数字被选中的概率为1/i即可保证当前的i个数字被选中的概率相等。因为截止目前见到的数字总共有i个,可以分成两个部分,即前i-1个数和第i个数,第i个数被选中的概率为1/i,那么不被选中的概率就为 (i-1)/i ,这时被选中的应该是前i-1个数中的一个,由假设可知前i-1个数被选中的概率相等,那么前i-1个数字任一一个被选中的概率为 ((i-1)/i)/(i-1) = 1/i。
8. 给出从n个数中随机选择m个的方法。注意,n非常大,并且一开始不知道其具体值。数字是一个一个给你的,当给完之后,你必须立刻给出随机的结果。
本题是上一题的扩展。
首先前m个数是必须取的,问题就变成了,当第i(i>m)个数到来时,是丢弃这个数还是保留这个数,如果保留这个数(第i个数),那么就需要从已选的m个数中选中一个丢弃。
具体做法是,选取前m个数,依次读取第i(i>m)个数,并以 m/i 的概率决定是否选择这个数,如果选择了这个数,则随机的替换掉当前m个数中的任意一个。
具体解释如下:
假设前i-1个数字任一个被选中的概率相等,为 m/(i-1)。
当第i个数字到来时被选中的概率为m/i(由定义可知),现在计算前i-1个数字中任一一个数字 k 被保留的概率,有两种情况:[1]第i个数字没被选中,那么k直接被保留,概率为(1-m/i); [2] 第i个数字被选中(m/i),并且删除当前m个数字中的一个,被删除的数字不是k(1-1/m),于是k仍然被保留的概率为 (m/(i-1)) * [ (1-m/i) + (m/i) * (1-1/m) ] = m/i
由数学归纳法依次类推,当遍历完n个数,选中m数中,每个数被选择的概率都是相等的。
概率题
1. 在半径为1的圆中随机选取一点
可作单位圆如下图所示,[-1,1]随机x的值,[-1,1]随机y的值,可以得到圆内随机一点 (x,y)。当然也可以使用极坐标进行随机。
2. 一根木棒,截成三截,组成三角形的概率是多少?
假设一个木棒长为1,三截的长度分别为 x, y , 1-x-y,由此可以转换成线性规划问题。
长度大于0小于1,因此有以下约束条件:
0 < x < 1
0 < y < 1
0 < 1-x-y < 1
(图中红色直线表示 x+y=1,因此满足以上三个约束的区域在红色直线以下的三角形区域,概率为: 1*1*(1/2) = 1/2 )
又由三角形两边之和大于第三边的条件有以下三个约束:
x + y > 1 - x - y
x + 1-x-y > y
y + 1-x-y > x
化简有:
x + y > 1/2
y < 1/2
x < 1/2
(由约束可得图中阴影部分,概率为: (1/2)*(1/2)*(12) = 1/8)
综合以上所有约束有:
一根木棒,截成三截,组成三角形的概率是: (1/2)*(1/8) = 1/16
参考:
[1] http://blog.csdn.net/dengm155/article/details/52658836
[2] https://zhidao.baidu.com/question/1737334723808514107.html