蓄水池抽样算法
蓄水池抽样是个很有趣的问题,这个问题的来源是关于等概率抽样的一种思考,问题是,如何能在不知道总体对象数量(或者数量巨大)的情况下抽取k个对象,使得每个对象被抽取到的概率相同。
解决问题的思路:考虑最终一定要抽取到k个对象,所以先任意抽出k个,然后对剩下的对象分别以某种概率概率,使得最终每个对象被抽到的概率相同。(根据分步分类计数原理即可证明)
算法流程:
- 输入:长度为N的数组L(N未知或者很大);输出:被等可能抽出的长度为k的数组l
- 对输入L取前k个数组成的数组作为蓄水池
- 对于L的第i(i=k+1,k+2,…,N)个数,任取r为0~i-1之间的整数,若r>k-1,则不进行替换,若r<=k-1,则用第i个数去替换蓄水池中第r个数
- 遍历一遍L,取到的l中的每个元素都是以概率k/n等可能取到的
python实现如下:
#coding=utf-8
'''
Created on 2016年9月15日
Reservoir sampling的python实现
@author: whz
'''
import numpy