蓄水池抽样 - Reservoir Sampling

最近在准备 Google 的面试, 刷面经的时候遇到了关于 Reservoir Sampling 的问题, 感觉很有趣来和大家分享下!


问题描述: 现在有一个很大、未知长度的数据流, 并且只能遍历一次, 我们现在要设计一个算法来选择数据,使被选中的任何一个数据的概率是相等的。

Say you have a stream of items of large ad unknown length that we can only iterate over once. Create an algorithm that randomly choose an item form this stream such that each item is equally likely to be selected.  ( 这是英文原版, 以防止我翻译的不好=.=)


思路: 假设我们知道这个很大\未知长度的数据流( stream[] )的最终长度为 N, 那么每个被选择的概率就是1/ N. 那么我们可以先将1 to k个数据放到一个 list 里面, 这个list 的大小就是 k

1.对于 i 满足 0 <= i <= k 的时候原来在 list 中的数据不被替换的概率就是 P = ( k/(k+1) * (k+1)/(k+2) *.....*(n-1)/n) = k / n;

也就是说 当我们遍历整个数据流完成的时候, 某个 数据还存在 在list 中的概率就是 P 

2.对于 i 满足 k < i <= N 的时候,新的数据( 不在list中的数据被选择替换到list中的数据) 被选择的概率

P(stream[n]) = k / N            //最后一个数据在最终版的list中的概率

P(stream[n-1]) = k/(n-1) * (n-1)/n          //倒数第二个数据在最终版的list中概率 

    被挑选进入list的概率   *     下一个元素挑选的index不等于该index的概率( 不被再选出来的概率)

   P(stream[n-2]) = k/(n-2) * (n-2)/(n-1) * (n-1)/n = k/n


这样就保证了所以数据被挑选的概率是 K/N. 


有问题欢迎指出!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值