蓄水池问题分析证明

来源:互联网 发布:win7禁止软件自动更新 编辑:程序博客网 时间:2024/04/29 23:39

这几天一直在讨论面试的问题,今天小伙伴们提到了微软面试的蓄水池问题,问题描述是这个样子的:

有1,2,...,n。 n个数据依次传过来,现在给你一次机会读取数据,你该以什么策略读,才能保证每个数据被读到的可能性是一样的?

问题的难点在于后面数据的不可知性,如果一次把n个数据全部获得,那么我们只需要简单的生成一个1-n的随机数,然后根据这个随机数取对应的元素即可。

但是现在数据一个一个到来,对于每一个数据都应该以某种策略决定取舍,保证不论当前来了多少个数据,这之前的数据(包含该数据)被读取的概率都是均等的。


基本的策略就是第i个数据到来时,总以1/i 的概率读取他。下面证明这种方法的正确性:

采用数学归纳法,从后向前证明,首先考察第n个元素,当他到来时,我们以1/n 的概率读取他,因此最终读取到的数据有1/n 的可能是n,1-1/n的概率是其他值。符合题目要求。那么考察第n-1个元素,当第n-1个元素到来时,我们必须要读取他,最后n个数据传完后,我们读到的数据才有可能是n-1。注意是有可能而已,因为若第n个数据到来,且我们读取了的话,那么最后的结果就不是n-1了,而是n,因此最后结果是n-1的概率是1/(n-1) * (1-1/n),即1/n。同理,第n-2个数据被最终显示的概率为1/(n-2) * (1- 1/(n-1)) * (1-1/n),即1/n。以此类推,得证。


该问题还有一个衍生,还是n个数据,现在有一个容量为k的池(k<=n),要保证所有数据被加入到池中的概率都是一样的。

分析可以知道,n个元素等概取k个,那么每个元素被取到的概率都是k/n。那么我们还是采用如下策略:

当第k个数据到来时,我们以k/i 的概率将它添加到池中,下面证明每个数据被加入池中的概率都是k/n。

考察第n个元素,当他到来事,我们以k/n的概率把他添加到池中,这样做了之后,池中一定有n,符合题目要求

那么当第n-1个元素到来时,首先我们必须要把他添加到池中,他最后才有可能出现在池中,前提是后面的元素到来时没有把他替换。那么添加n-1的概率是k/(n-1),然后第n个元素到来时不添加到池,或者添加进池但不替换n-1,这个和事件即为P,那么P的补集就是n添加进池且替换n-1 (~~~1/k的概率~~~),那么这个事件的概率是(k/n) * (1/k)。因此n-1最终出现在池中的概率为k/(n-1) * (1- (k/n) * (1/k)),即k/n。第n-2个元素最终出现在池中的概率是 k/(n-2) * {1-[k/(n-1)*(1/k) + (1-k/(n-1)*(1/k) ) * (k/n) * (1/k)]},即k/n。以此类推,得证。

PS:前k个元素到来时,k/i 是大于1的,这时就以概率1添加即可。

严格的数学归纳法:当第k个数据到来时,以概率1添加,这时1-k中所有元素在池中的概率都是1,即k/k,满足题目要求;

假设第n-1数据处理完毕后,1至n-1这n-1个元素被添加到池的概率是等概的,即都是k/(n-1),下面需要证明n元素到来并处理后,1-n这些元素出现在池中的概率是k/n。

证明如下:

1-n分为两部分:1至n-1,和n,设i为1~n-1中任意一数,那么n处理后他出现在池中的概率是k/(n-1) * (1 - k/n * (1/k)) = k/n

对于n,显然处理后他出现在池中的概率也是k/n。

故得证~~

0 0
原创粉丝点击