Reservoir sampling 数组随机等概率选择样品

给定一个数组,数组大小N,随机选择K个样品。


如果K比较小,可以随机生成K个在[0,N)之间的不重复的数,然后以这K个数作为index在原始数组中选择样品。

但是如果K比较大,比如N=100000000,K=10000000,那么如何快速生成K个限定范围的不重复的随机数?

可以构造一个大小为N的循环链表,初始化一个指针指向起点。随机生成一个数r,把指针往后移动r个位置,选择这个数作为样品,删除这个节点,并且把指针往后移动一位。重复以上步骤K次得到所有样品。

但是上面的方法空间复杂度是O(N),并且如果N的大小未知呢?


这里是从wikipedia找到的伪代码

array R[k];    // result
integer i, j;

// fill the reservoir array
for each i in 1 to k do
    R[i] := S[i]
done;

// replace elements with gradually decreasing probability
for each i in k+1 to length(S) do
    j := random(1, i);   // important: inclusive range
    if j <= k then
        R[j] := S[i]
    fi
done


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值