前言:

  蓄水池抽样:从N个元素中随机的等概率的抽取k个元素,其中N无法确定。

适用场景:

  模式识别等概率抽样,抽样查看渐增的log日志(无法先保存整个数据流然后再从中选取,而是期望有一种将数据流遍历一遍就得到所选取的元素,并且保证得到的元素是随机的算法)。

伪代码:

init : a reservoir with the size: k
for i= k+1 to N
M=random(1, i);
if( M < k)
SWAP the Mth value and ith value
end for

  解释:先选中第1到k个元素,作为被选中的元素。然后依次对第k+1至第N个元素做如下操作:每个元素都有k/x的概率被选中,然后等概率的(1/k)替换掉被选中的元素。其中x是元素的序号

原理:

  蓄水池抽样算法:

  1. 先选取个元素中的前个元素,保存在集合中;
  2. 从第个元素开始,每次先以概率选择是否让第个元素留下。若第个元素存活,则从中随机选择一个元素并用该元素替换它;否则直接淘汰该元素
  3. 重复1和2,直到结束。最后集合中剩下的就是保证随机抽取的个元素。

  蓄水池抽样算法正确性证明:
    为了证明该算法的正确性,我们要保证算法结束后,原个元素每一个最后存活下来的概率都是(因为从个元素中随机抽取个元素,每个元素被抽中的概率都是)。形式化地,我们要证明的结论是:在算法的第i(0<=i<=n-k)轮,前k+i个元素每一个存活下来的概率是k/k+i 。

数学归纳证明:

时,结论显然成立。

时,根据算法,元素存活的概率为。而对于元素,有两种情况会使其存活下来:要么元素直接被淘汰;要么元素留下,但是没有替换掉元素。由归纳假设,时结论成立,故元素存活的概率为,得证

  举例描述辅助数学证明:

每次都是以 k/i 的概率来选择,例: k=1000的话, 从1001开始作选择,1001被选中的概率是1000/1001,1002被选中的概率是1000/1002,与直觉是相符的。

假设当前是i+1, 按照我们的规定,i+1这个元素被选中的概率是k/i+1,也即第 i+1 这个元素在蓄水池中出现的概率是k/i+1,

此时考虑前i个元素,如果前i个元素出现在蓄水池中的概率都是k/i+1的话,说明我们的算法是没有问题的。

对这个问题可以用归纳法来证明:

  1. k < i <=N 1.当i=k+1的时候,蓄水池的容量为k,第k+1个元素被选择的概率明显为k/(k+1), 此时前k个元素出现在蓄水池的概率为 k/(k+1), 很明显结论成立。

2.假设当 j=i 的时候结论成立,此时以 k/i 的概率来选择第i个元素,前i-1个元素出现在蓄水池的概率都为k/i。

3.证明当j=i+1的情况: 即需要证明当以 k/i+1 的概率来选择第i+1个元素的时候,此时任一前i个元素出现在蓄水池的概率都为k/(i+1). 前i个元素出现在蓄水池的概率有2

部分组成, ①在第i+1次选择前得出现在蓄水池中,②得保证第i+1次选择的时候不被替换掉 ①.由2知道在第i+1次选择前,任一前i个元素出现在蓄水池的概率都为k/i ②.考虑

被替换的概率: 首先要被替换得第 i+1 个元素被选中(不然不用替换了)概率为 k/i+1,其次是因为随机替换的池子中k个元素中任意一个,所以不幸被替换的概率是 1/k,故

前i个元素(池中元素)中任一被替换的概率 = k/(i+1) * 1/k = 1/i+1 则(池中元素中)没有被替换的概率为: 1 - 1/(i+1) = i/i+1 综合① ②,通过乘法规则 得到前i个元素出现在蓄水池

的概率为 k/i * i/(i+1) = k/i+1 故证明成立!!!

实现代码和伪代码类似,就不赘述了

蓄水池抽样(原理&实现)的更多相关文章

  1. Reservoir Sampling - 蓄水池抽样

    问题起源于编程珠玑Column 12中的题目10,其描述如下: How could you select one of n objects at random, where you see the o ...

  2. Reservoir Sampling - 蓄水池抽样问题

    问题起源于编程珠玑Column 12中的题目10,其描述如下: How could you select one of n objects at random, where you see the o ...

  3. 【算法34】蓄水池抽样算法 (Reservoir Sampling Algorithm)

    蓄水池抽样算法简介 蓄水池抽样算法随机算法的一种,用来从 N 个样本中随机选择 K 个样本,其中 N 非常大(以至于 N 个样本不能同时放入内存)或者 N 是一个未知数.其时间复杂度为 O(N),包含 ...

  4. Reservoir Sampling - 蓄水池抽样算法&&及相关等概率问题

    蓄水池抽样——<编程珠玑>读书笔记 382. Linked List Random Node 398. Random Pick Index 从n个数中随机选取m个 等概率随机函数面试题总结 ...

  5. leetcode398 and leetcode 382 蓄水池抽样算法

    382. 链表随机节点 给定一个单链表,随机选择链表的一个节点,并返回相应的节点值.保证每个节点被选的概率一样. 进阶:如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现? 示 ...

  6. C#LeetCode刷题-蓄水池抽样

    蓄水池抽样篇 # 题名 刷题 通过率 难度 382 链表随机节点   47.0% 中等 398 随机数索引   41.6% 中等

  7. 【数据结构与算法】蓄水池抽样算法(Reservoir Sampling)

    问题描述 给定一个数据流,数据流长度 N 很大,且 N 直到处理完所有数据之前都不可知,请问如何在只遍历一遍数据(O(N))的情况下,能够随机选取出 m 个不重复的数据. 比较直接的想法是利用随机数算 ...

  8. C# 蓄水池抽样

    蓄水池采样算法解决的是在给定但长度未知的大数据集中,随机等概率抽取一个数据.如果知道数据的长度,可以用随机数rand()%n得到一个确切的随机位置,或者分块取值来构造随机,那么该位置的对象就是所求的对 ...

  9. Reservoir Sampling 蓄水池抽样算法,经典抽样

    随机读取数据,如何保证真随机是不可能的,因为计算机的随机函数是伪随机的. 但是在不考虑计算机随机函数的情况下,如何保证数据的随机采样呢? 1.系统提供的shuffle函数 C++/Java都提供有sh ...

随机推荐

  1. C#文本框允许使用ctrl+A

    C#文本框中默认是不允许使用全选的.可以通过以下事件完成: private void textBox1_KeyDown(object sender, KeyEventArgs e) { if (e.C ...

  2. 解决 Eclipse build workspace validation javascript 慢的问题

    参考: http://blog.csdn.net/zhangzikui/article/details/24805935 http://www.cnblogs.com/wql025/p/4978351 ...

  3. 网络攻击技术开篇——SQL Injection

    本文转自: http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html 1.1.1 摘要 日前,国内最大的程序员社区CSDN网站的用户数据库 ...

  4. openstack安装文档

    #########################################openstack m版本部署安装################################## 控制节点.网络 ...

  5. Dynamics CRM 2015-Form之控制Ribbon Button

    在上一篇中,我用一个例子,简单介绍了如何添加Ribbon Button,以及如何理解RibbonDiffXml,对这方面还不清楚的,可以先看看这篇博文:Dynamics CRM 2015-Form之添 ...

  6. Qt之hello world

    本人使用的是Qt5.7版本的,请读者自主下载安装. 今天首先来进行Qt入门的第一个程序,也是很经典的一个例子.这是在很多的变成语言中都会用到的例子,就是输出helloworld这个信息.Qt中使用的变 ...

  7. Dockerfile注意事项

    准则 尽量将Dockerfile放在空目录中,如果目录中必须有其他文件,则使用.dockerignore文件. 避免安装不必须的包. 每个容器应该只关注一个功能点. 最小化镜像的层数. 多行参数时应该 ...

  8. Java重写equals()和hashCode()

    1.何时需要重写equals() 当一个类有自己特有的 ”逻辑相等”概念(不同于对象身份的概念). 2.设计equals() [1]使用instanceof操作符检查 ”实参是否为正确的类型”. [2 ...

  9. angular : direative : autoResize textarea auto resize

    今天为大家推出自己的auto resize 指令功能. 目的:解决textarea在给height的问题. 参考源码:http://monospaced.github.io/angular-elast ...

  10. Github创建分支

    一.clone Repository clone Github 上的Repository,如下: git clone git@github.com:FBing/design-patterns.git ...