蓄水池抽样问题

题目:

微软电面问到的问题,前面提了一大堆背景,最后归结为一个问题,如何在连续的网络流量中,等概率随机抽取1个数据包。

分析:

参加电面时,还没看过蓄水池抽样问题,后来回来一搜,这就是典型的蓄水池抽样问题,不过当时自己也想到了一种解法,使用一个变量保存数据包,从1到i个数据包,每次遇到第i个数据包,以1/i的概率选取这个数据包,并且替换原来的数据包,这样到第n个数据包,我们能保证我们以1/n的概率选取这n个数据包中的1个。

证明:

加入第i个数据包到来,我们以1/i的概率选取这个数据包,显然,它的概率是符合的,那么第i-1个数据是不是也符合呢?我们假设第i-1次取数据包时,前面i-1个数据包以1/(i-1)的概率选取,那么第i-1个数据包被保留下来的概率是1-p(第i个数据包保存)再乘上p(1到i-1次选择被保存的概率),这里p(1到i-1次选择被保存的概率)就是假设的1/(i-1),那么第i次取包,前i-1个数据包被保存的概率是:

(1 - 1/i) * 1/(i - 1) = 1/i,说明前i-1个数据包的选取概率也是1/i;

由此进行归纳,可以得到最终结果。

扩展:

考虑蓄水池中抽取k个元素。

方法还是一样,假设前i次选择时,前i个数据包被选到水库的概率是k/i,那么第i+1次选择时,前面i个数据包保留在水库中的概率是

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

所以第i+1次选择,所有的数据包还是以k/(i + 1)的概率保存到水库中,得证。

伪代码如下:

Init : a reservoir with the size: k
        for    i= k+1 to N
            M=random(1, i);
            if( M < k)
                 SWAP the Mth value and ith value
       end for

总结:

蓄水池问题非常经典,而且非常实用,需要理解其中原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值