蓄水池采样算法(Reservoir Sampling)
2017-03-12 15:09
274 查看
蓄水池采样算法:
问题描述:
采样问题经常会被遇到,比如:从 100000 份调查报告中抽取 1000 份进行统计。
从一本很厚的电话簿中抽取 1000 人进行姓氏统计。
从 Google 搜索 “Ken Thompson”,从中抽取 100 个结果查看哪些是今年的。
这些都是很基本的采用问题。
既然说到采样问题,最重要的就是做到公平,也就是保证每个元素被采样到的概率是相同的。所以可以想到要想实现这样的算法,就需要掷骰子,也就是随机数算法。(这里就不具体讨论随机数算法了,假定我们有了一套很成熟的随机数算法了)
对于第一个问题,还是比较简单,通过算法生成 [0,100000−1)[0,100000−1) 间的随机数 1000 个,并且保证不重复即可。再取出对应的元素即可。
但是对于第二和第三个问题,就有些不同了,我们不知道数据的整体规模有多大。可能有人会想到,我可以先对数据进行一次遍历,计算出数据的数量 NN,然后再按照上述的方法进行采样即可。这当然可以,但是并不好,毕竟这可能需要花上很多时间。也可以尝试估算数据的规模,但是这样得到的采样数据分布可能并不平均。
问题本质:
从一个序列中随机抽取不重复的k个数,保证每个数被抽取到的概率相等。求解:
首先构建一个可放k个元素的蓄水池,将序列的前k个元素放入蓄水池中。然后从第k+1个元素开始,以k/n的概率来决定该元素是否被替换到池子中。 当遍历完所有元素之后,就可以得到随机挑选出的k个元素。复杂度为O(n).
其伪代码如下:
Init: a reservoir with size k for i=k to N-1 //index start from 0 M= random(1, i); if (M<k) SWAP the Mth element with the ith end for
证明:
求证:每个数被取到的概率为k/n。http://www.cnblogs.com/snowInPluto/archive/2016/10/25/5996269.html
http://www.cnblogs.com/ywl925/p/3793003.html
相关文章推荐
- Reservoir Sampling 蓄水池抽样算法,经典抽样
- 随机抽样——蓄水池抽样算法(Reservoir Sampling)
- Reservoir Sampling 蓄水池抽样算法,经典抽样
- 蓄水池(Reservoir_sampling)抽样算法简记
- 大数据算法MOOC笔记3:水库抽样Reservoir Sampling(蓄水池问题)
- 【算法34】蓄水池抽样算法 (Reservoir Sampling Algorithm)
- 蓄水池抽样算法 (Reservoir Sampling Algorithm)
- [编程题] LeetCode上的Reservoir Sampling(蓄水池算法)类型的题目
- 蓄水池抽样算法 (Reservoir Sampling Algorithm)
- Reservoir Sampling - Sampling from a stream of elements(蓄水池算法,从流数据中抽样)
- 随机抽样问题(蓄水池问题Reservoir Sampling)
- 68. 蓄水池抽样(Reservoir Sampling)
- 蓄水池抽样(Reservoir sampling)
- Reservoir Sampling - 蓄水池抽样
- Reservoir Sampling - 蓄水池抽样
- 有关蓄水池抽样(Reservoir Sampling)和自己的一些思考
- Reservoir Sampling - 蓄水池抽样问题
- Reservoir Sampling - 蓄水池抽样
- 蓄水池问题Reservoir Sampling
- 随机抽样问题(蓄水池问题Reservoir Sampling)