随机抽样问题(蓄水池问题Reservoir Sampling)
随即抽样问题:
要求从N个元素中随机的抽取k个元素,其中N无法确定。
是在 《计算机程序设计与艺术》 中看到的这个题目,书中只给出了解法,没给出证明。
解决方法是叫Reservoir Sampling (蓄水池抽样)
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
证明:
每次都是以 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的话,说明我们的算法是没有问题的。
对这个问题可以用归纳法来证明: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。
证明当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
故证明成立
随机抽样问题(蓄水池问题Reservoir Sampling)的更多相关文章
- 68. 蓄水池抽样(Reservoir Sampling)
[本文链接] http://www.cnblogs.com/hellogiser/p/reservoir-sampling.html 问题起源于编程珠玑Column 12中的题目10,其描述如下: H ...
- Reservoir Sampling 蓄水池采样算法
https://blog.csdn.net/huagong_adu/article/details/7619665 https://www.jianshu.com/p/63f6cf19923d htt ...
- 蓄水池采样算法(Reservoir Sampling)
蓄水池采样算法 问题描述分析 采样问题经常会被遇到,比如: 从 100000 份调查报告中抽取 1000 份进行统计. 从一本很厚的电话簿中抽取 1000 人进行姓氏统计. 从 Google 搜索 & ...
- Reservoir Sampling - 蓄水池抽样
问题起源于编程珠玑Column 12中的题目10,其描述如下: How could you select one of n objects at random, where you see the o ...
- Reservoir Sampling - 蓄水池抽样问题
问题起源于编程珠玑Column 12中的题目10,其描述如下: How could you select one of n objects at random, where you see the o ...
- 【算法34】蓄水池抽样算法 (Reservoir Sampling Algorithm)
蓄水池抽样算法简介 蓄水池抽样算法随机算法的一种,用来从 N 个样本中随机选择 K 个样本,其中 N 非常大(以至于 N 个样本不能同时放入内存)或者 N 是一个未知数.其时间复杂度为 O(N),包含 ...
- 蓄水池抽样算法 Reservoir Sampling
2018-03-05 14:06:40 问题描述:给出一个数据流,这个数据流的长度很大或者未知.并且对该数据流中数据只能访问一次.请写出一个随机选择算法,使得数据流中所有数据被选中的概率相等. 问题求 ...
- 【数据结构与算法】蓄水池抽样算法(Reservoir Sampling)
问题描述 给定一个数据流,数据流长度 N 很大,且 N 直到处理完所有数据之前都不可知,请问如何在只遍历一遍数据(O(N))的情况下,能够随机选取出 m 个不重复的数据. 比较直接的想法是利用随机数算 ...
- 算法系列:Reservoir Sampling
copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...
随机推荐
- Java Array 方法和使用
1.Arrays.toString():数组转字符串 格式:Arrays.toString(数组名) 将数组转化成字符串,此时输出的结果是字符串类型. import java.util.Arrays; ...
- json工具性能比较:json-lib和jackson进行Java对象到json字符串序列化[转]
网上查找“java json”,发现大家使用最多的还是json-lib来进行java对象的序列化成json对象和反序列化成java对象的操作.但是之前在网上也看到过一往篇关于json序列化性能比较的文 ...
- ThinkPHP Http工具类(用于远程采集 远程下载) phpSimpleHtmlDom采集类库_Jquery筛选方式 使用phpQuery轻松采集网页内容http://www.thinkphp.cn/extend/541.html
[php]代码库 view sourceprint? <?php // +------------------------------------------------------------ ...
- hotplug_uevent机制_修改mdev配置支持U盘自动挂载学习笔记
1.接入U盘,看输出打印信息并分析 (1)输出信息 自动创建设备节点 (2)用ls命令查看 这里/dev/sda表示整个U盘,/dev/sda1表示这个U盘的第一个分区. (3)手动挂载,查看文件,手 ...
- GIL线程与进程选择
#!/usr/bin/env python # encoding: utf-8 # Date: 2018/6/18 # 计算密集型.应该启动多进程# from multiprocessing imp ...
- 数据库DRDS中间件介绍
DRDS/TDDL alibaba. Distributed Relational Database Service. 阿里分布式数据库DRDS的前身是淘宝分布式数据库层TDDL,大概在2012年的时 ...
- 异步编程之co——源码分析
异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...
- C# 重构
重构是在编写代码后在不更改代码的外部行为的前提下通过更改代码的内部结构来改进代码的过程. 一.何时需要重构 1.代码中存在重复的代码: 如果类中有重复的代码块,需将其提炼出一个新的独立方法,如果是不同 ...
- LeetCode题解 #1 Two Sum
在LeetCode做的第一到题 题目大意:给出n个数,在其中找出和为一个特定数的两个数. Input: numbers={2, 7, 11, 15}, target=9Output: index1=1 ...
- subprocess in python3.5
subprocess 该子模块允许你创建新的流程,连接到它们的输入/输出/错误管道,并获取他们的返回值.该模块打算替换多个旧的模块和功能:os.system 和 os.spawn * 使用sub ...