蓄水池算法简介

 
 
从N个元素中随机抽取k个元素,但是N不定。每个元素抽取的概率是k/N。
解答:先选中前k个,从k+1到最后一个元素,以1/i (i = k+1, k+2, ... N)的概率选中第i个元素,并且随机替换一个原来选中的元素。

'''
 Reservoir Sampling implementation
'''
from random import Random

def RandomSelect(knum, rand=None):
    ''' (int, func) -> list

    Reservoir Sampling implementation
    >>> myList = [1,2,3,4,5,6,7,8,-1] 
    >>> ge = RandomSelect(3)
    >>> ge.next()
    >>> for v in myList:
            cr.send(v)
    '''
    selection = None
    k_elems_list = []
    count = 0
    if rand is None:
        rand = Random()
    while True:
        item = yield selection
        if item == -1:
            break
        if len(k_elems_list) < knum:
            k_elems_list.append(item)
        elif rand.randint(0, count) == 0:
            index = rand.randint(0, knum-1)
            k_elems_list.pop(index)
            k_elems_list.insert(index, item)
        count += 1
    print k_elems_list

if __name__ == '__main__':
    myList = [1,2,3,4,5,6,7,8,-1]
    cr = RandomSelect(3);
    cr.next() # advance to the yield statement, otherwise I can't call send
    try:
        for val in myList:
            cr.send(val)
    except StopIteration:
        pass
    finally:
        del cr



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值