蓄水池抽样算法

问题定义

长度为N的链表,N很大,但是不知道具体有多大。从N个元素中随机取出K个元素,只能遍历一次链表。用到的算法保证取出的元素恰好有K个,且他们是完全随机的(出现概率均相等)。

求解

该算法是针对从一个序列中随机抽取不重复的K个数,保证每个数被抽取到的概率为k/n这个问题而构建的。做法是:
首先构建一个可放K个元素的蓄水池,将序列的前K个元素放入蓄水池中。然后从第K+1个元素开始,以K/n的概率来决定该元素是否被替换到池子中,当遍历完所有元素之后,就可以得到随机挑选出的K个元素。复杂度为O(n)
其伪代码如下:
Init : a reservor(蓄水池) 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

证明

1.对于第i个数(i <K,在前K步被选中的概率是1,从第一步开始,i不被选中的概率为K/K+1,那么读到第n个数时,第i个数(i < k)被选中的概率 = 被选中的概率* 以后每一步不被换走的概率,即:1  * K/K+1 *  k+1/K+2  *……*n-1/n = K/n
2.对于第j个数(j>=K)

 蓄水池抽样算法i是一系列的堆积算法,其目的在于从包含n个项目的集合S中选取K个样本,其中n为一很大或未知的数量,尤其适用于不能把所有n个项目都放在主内存的情况。

证明当前任意一行为取出行的概率为1/i,i为当前扫描到的行号,也即每一行取出的概率相等    我们用数学归纳法来证明, 当i=1时,当前只浏览了第一行,因此第一行为取出行的概率为1/1=1,符合直接取出的条件 当i=k时,有前k行为取出行的概率为1/k,我们要证明的是,当i=k+1时,前k+1行每一行被取出的概率均相等,且为1/(k+1)。当扫描到第k+1行时,我们以1/(k+1)概率替换choice,易知,第k+1行为choice的概率即为1/(k+1),对于第k行,其为choice的概率是 第k行为取出行的概率 * 第k+1行没有被取出的概率即,对于第k行的证明同样可应用到前k-1行,对于其中第m行其为choice的概率是 第m行为取出行的概率 * 第m+1行没有被取出的概率 * … *第k+1行没有被取出的概率,即由此证得当i=k+1时,所有行的取出概率为1/(k+1)。证毕

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值