一些常见的概率生成器的题目

来源:互联网 发布:用vb编写计算器的程序 编辑:程序博客网 时间:2024/05/19 17:50

转自:http://blog.163.com/kevinlee_2010/blog/static/16982082020120792429856/

百度的一个面试题目:

.已知一随机发生器,产生0的概率是p,产生1的概率是1-p,现在要你构造一个发生器, 
使得它构造0和1的概率均为1/2;构造一个发生器,使得它构造1、2、3的概率均为1/3;…, 
构造一个发生器,使得它构造1、2、3、…n的概率均为1/n,要求复杂度最低。

初看确实有点头晕,也没什么思路。但是仔细想想为什么生成0和1的概率均为1/2,我们可以看成是生成0和1的概率是均等的。这样想之后,似乎就没那么不好理解了。

原始的随机数生成器,生成0 的概率为p,生成1的概率为1-p,那么怎么构造才能使得生成0和1的概率相等呢。或者说有两个独立的事件的概率是相等呢?

这样来做一下,让该随机数生成器生成两个数,那么序列是00,01,10,11概率分别为 p*p,p(1-p),(1-p)p,(1-p)*(1-p)

很明显,这四种情况中存在两个独立的事件概率是相等。也就是01和10,那么我把01看成是0,10看成是1,那么他们输出的概率均为p(1-p),其他的情况舍弃。这样就得到了0和1均等生成的随机器了。

思维在扩展一下,生成1,2,…n的概率分别是1/n,也就是均等的。那么我们可以想怎么生成一个序列,里面有n个独立时间,概率是相等。而且我们能够猜测到这些概率的形式为 p^x*(1-p)^y,如果要相等,那么x必须等于y.这样就说明了序列中0和1的个数是相等的。而且这样的情况必须有多与n个才行。

数学表示就是 C(2x,x) >=n ,我们只需要知道x就能够知道序列要多长了。而且中间必定有超过n个概率为{p(1-p)}^x不相等序列。

问题就可以解决了。

其实卡我的问题是,丢掉那些多余的,只要n个等概率的序列,是否真的是等概率的(最终输出)。

腾讯面试题:

已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。

利用的方法和上个问题类似,如何能够得到一个等概率的独立事件。这个问题和上个问题不同的是,这里产生的序列,要变成和的形式或者其他的形式,那么概率就会发生变化了。

如果能够得到一组等概率的数,不管是什么数,只要等概率而且个数大于10,那么问题就可以解决了。

发现(rand7()-1)*7+rand7(),可以等概率的生成1到49。

呵呵,这不就得了,只要把11-49砍掉就可以了。不过这样的效率比较低。可以砍掉41-49,然后在把1-40映射到1-10,那么问题也就解决了。

腾讯面试题:

等概率采样数据流中的数字。

比如从数据流中等概率的采样k个数字。

怎么做呢?先拿到最开始的k个数字,然后以后的每个数字等概率的和这k个数字交换。那么就可以达到每个数字被抽取的概率是等概率的。

怎么证明呢?

采用归纳方法,假设前n个数字等概率的采样k个数字,那么每个数字被采样的概率为k/n,现在新来一个数字,变成了n+1个数字,那么每个数字被采样的概率变位k/(n+1),我们要证明这个

这个问题在计算机程序设计艺术书中提到,叫Reservoir Sampling(蓄水池采样),属于随机算法的一种。

现在假定存在了n个数字,来了第n+1个数字,那么第n+1个数字被选择的概率是k/n+1,那么我们推算其他的数字被选择的概率也是k/n+1

P(其余数字) = p(其余数字|第n+1个选择)*p(第n+1个选择) + p(其余数字|第n+1个不选择)*p(第n+1个不选择)

                      =  k/n*(1-1/k)*k/(n+1) + k/n*(n+1-k)/(n+1)

                      = k*(k-1) / (n *(n+1) ) + k*(n+1-k) / (n*(n+1))

                      = k*n/(n *(n+1))

                      = k/(n+1)

得证。其余数字被选择的概率依然也是 k/(n+1)

问题:

描述RANDOM(a,b)的过程的一种实现,它只调用RANDOM(0,1)。作为a和b的函数,你的程序的期望运行时间是多少?
注:RANDOM(0,1)以等概率输出0或者1,
      要求RANDOM(a,b)以等概率输出[a,b]之间的数(整数)

 

解决方案:

         1,取 n=b-a+1,取最小的正整数m,使得 2^m >= n
         2,调用RANDOM(0,1),输出m-bit位整数N   (  N >= 0 and N <= 2^m-1)
         3,  if   N >=0  and N <= b-a
                      then return a+N     
                else 重新执行步骤 2
 
[a,b]之间每个数都是以 1/2^m 的概率输出的  

渐进运行时间分析:

我觉得渐进时间分析应该用概率分析的方法,我觉得是服从几何分布
     假设进行一系列伯努利试验,每次成功的概率是p,失败的概率是q=1-p,在取得一次成功前一共要进行多少次试验?令随机变量X为取得一次成功所要进行的试验次数,则X的取值范围{1,2,......}。对k>=1,因为在一次成功前有k-1次失败,从而有
                                               Pr[X=k]= q^(k-1)p
满足上式的分布称为几何分布     [见算法导论 P686]
在算法中 p=(b-a+1)/2^m   
期望运行次数(算法中生成m位序列的调用次数)为:  E[X]=sum(k*q^(k-1)p) [k=1......+无穷]=1/p=2^m/(b-a+1)
用T表示调用一次RANDOM(0,1)所需要的时间,每次运行时间为输出m位bit的时间:O(log(b-a) × T)
期望运行时间:O(T × log(b-a) × 2^m/(b-a+1) )=(约等于)O(T × log(b-a))  (因为m=(约等于)log(b-a+1))