面试常考蓄水池算法详解

问题描述分析:

采样问题经常会被遇到,比如:

1. 从 100000 份调查报告中抽取 1000 份进行统计;

2. 从一本很厚的电话簿中抽取 1000 人进行姓氏统计;

3. 从 Google 搜索 "Ken Thompson",从中抽取 100 个结果查看哪些是今年的。

既然说到采样问题,最重要的就是做到公平,也就是保证每个元素被采样到的概率是相同的。所以可以想到要想实现这样的算法,就需要掷骰子,也就是随机数算法。(这里就不具体讨论随机数算法了,假定我们有了一套很成熟的随机数算法了)

对于第一个问题,还是比较简单,通过算法生成 [0,100000−1)[0,100000−1) 间的随机数 1000 个,并且保证不重复即可。再取出对应的元素即可。

但是对于第二和第三个问题,就有些不同了,我们不知道数据的整体规模有多大。可能有人会想到,我可以先对数据进行一次遍历,计算出数据的数量 N,然后再按照上述的方法进行采样即可。这当然可以,但是并不好,毕竟这可能需要花上很多时间。也可以尝试估算数据的规模,但是这样得到的采样数据分布可能并不平均。

蓄水池算法:

终于要讲到蓄水池采样算法(Reservoir Sampling)了。先说一下算法的过程:

1. 假设数据序列的规模为 n,需要采样的数量的为 k。

2. 首先构建一个可容纳 k 个元素的数组,将序列的前 k 个元素放入数组中。

3. 然后从第 k+1 个元素开始,以 k/n 的概率来决定该元素最后是否被留在数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值