今天被百度鄙视了,唉!还是能力不够啊。回来看网上评论一大片,自己错的实在太离谱。有一个求概率的题目,我自己萌了半天,竟然不知到这是典型的蓄水池抽样算法。。。。
问题起源于编程珠玑Column 12中的题目10,其描述如下:
http://www.cnblogs.com/HappyAngel/archive/2011/02/07/1949762.html
How could you select one of n objects at random, where you see the objects sequentially but you do not know the value of n beforehand? For concreteness, how would you read a text file, and select and print one random line, when you don’t know the number of lines in advance?
问题定义可以简化如下:在不知道文件总行数的情况下,如何从文件中随机的抽取一行?
首先想到的是我们做过类似的题目吗?当然,在知道文件行数的情况下,我们可以很容易的用C运行库的rand函数随机的获得一个行数,从而随机的取出一行,但是,当前的情况是不知道行数,这样如何求呢?我们需要一个概念来帮助我们做出猜想,来使得对每一行取出的概率相等,也即随机。这个概念即蓄水池抽样(Reservoir Sampling)。
有了这个概念,我们便有了这样一个解决方案:定义取出的行号为choice,第一次直接以第一行作为取出行 choice ,而后第二次以二分之一概率决定是否用第二行替换 choice ,第三次以三分之一的概率决定是否以第三行替换 choice ……,以此类推,可用伪代码描述如下:
i = 0
while more input lines
with probability 1.0/++i
choice = this input line
print choice
这种方法的巧妙之处在于成功的构造出了一种方式使得最后可以证明对每一行的取出概率都为1/n(其中n为当前扫描到的文件行数),换句话说对每一行取出的概率均相等,也即完成了随机的选取。
回顾这个问题,我们可以对其进行扩展,即如何从未知或者很大样本空间随机地取k个数?
类比下即可得到答案,即先把前k个数放入蓄水池,对第k+1,我们以k/(k+1)概率决定是否要把它换入蓄水池,换入时随机的选取一个作为替换项,这样一直做下去,对于任意的样本空间n,对每个数的选取概率都为k/n。也就是说对每个数选取概率相等。
伪代码:
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)维护一个大小为 M 的数组. 记当前接收的是第 N 个数据(这里从 1 开始,代码中从 0 开始) (2)如果 N, 直接插入(对于前 M 个元素,
今天完成题目:398print( random.uniform(1.1,5.4) ) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数a=[1,
蓄水池抽样》 Blog: 《结构之法 算法之道》 Something about bit op: Something about array rotate: A Linear Time Majority Vote Algorithm 题解: Maximum Gap: Something about largest-rectangle-in-histogram:...
蓄水池算法 leetcode leetcode-cn.go 数组 267 动态规划 213 数学 190 字符串 187 树 155 深度优先搜索 132 哈希表 132 二分查找 92 贪心算法 78 广度优先搜索 74 双指针 70 栈 64 ...蓄水池抽样 2
蓄水池算法 leetcode leetcode-javascript-chimy 数据结构 1.数组 ...蓄水池抽样 3. 数学 4. 几何 5. 设计 6. 脑筋急转弯 字符串 数组 链表 队列 栈 排序 树 图 贪心算法 分治算法 回溯算法 动态规划
蓄水池算法 leetcode MyLeetCodeSummary ...蓄水池抽样 几何 Map 数组 哈希表 链表 数学 双指针 字符串 二分查找 分治算法 动态规划 回溯算法 Random Rejection Sampling Sliding Window Ordered Map Line Sweep
蓄水池算法 leetcode leetcode practice 动态规划 DynamicProgramming 贪心算法 GreedyAlgorithm 分治算法 DivideAndConquer 头脑风暴 ...蓄水池抽样 Array 数组 HashTable 哈希表 SegmenTree 线段树
这个题目有一种算法叫做蓄水池抽样,思路大致是这样的,先选中前m个, 从第m+1个元素到最后一个元素为止, 以m/i (i=m+1, m+2,...,N) 的概
技术点23 蓄水池抽样(reservoir 抽样) 4.4 本章小结 5 优化HDFS 处理大数据的技术 5.1 处理小文件 技术点24 使用Avro 存储大量小文件 5.2 通过压缩提高数据存储效率 技术点25 选择合适的压缩解码器 ...
join4.1.4 为你的数据挑选最优的合并策略4.2 排序4.2.1 二次排序技术点21 二次排序的实现4.2.2 整体并行排序技术点22 通过多个reducer 对key 进行排序4.3 抽样技术点23 蓄水池抽样(reservoir 抽样...
蓄水池JAVA 力码 旨在熟悉Java和python实现的算法和数据结构。 :) 如果你放弃,你只会输。 标签 大批 标题 解决方案 哈希表 标题 解决方案 链表 标题 解决方案 数学 标题 解决方案 细绳 标题 解决方案 两个指针 标题...
蓄水池算法leetcode 技术面试准备计划 从零开始学习数据结构和算法 如何: 数据结构:记笔记,画概念 此数据结构的算法:记笔记,绘制概念 从零开始实现数据结构及其算法 实施例程: 阅读问题说明 编写单元测试:...
leetcode双人赛 Leetcode刷题报告 目前进度是268道题了. 以及周赛还是无法做到全部AC. 与大神的差距还是较大的. ...兔子洞,蓄水池抽样。 话说,可能真的需要用个别的方式来组织这个代码了的。比如package的信息啥的。
蓄水池抽样算法 leetcode 382 更多可见算法与数据结构可见 数论 蔡勒公式 汉诺塔 计算机网络 [分组转发中的时延] [TDM, CDM, WDM, WDM, STDM] HTTP [多路复用能否取代打包工具] 编译技术 做语言的主人 Unix Linux ...
概率:洗牌算法、蓄水池抽样、蒙特卡洛 数论:素数,最小公倍数,最大公约数 位运算:异或,与的巧妙用法 特殊的数:有效数字(状态机),第n个丑数,平方数(DP解法),回文数 数字的转化:溢出检测、模拟运算...
leetcode蓄水池JAVA xiao-leetcode leet code src code, from easy to medium to hard, hahaha array backtracking(回溯) bit_manipulation breadth_first_search(深度优先遍历) depth_first_search(广度优先遍历) ...
非科班出身程序员刷题 个人刷题总结 数组问题 字符串 树 哈希表 动态规划 深度优先搜索 二分查找 贪心 双指针 广度优先搜索 栈 回溯算法 设计 链表 排序 堆 位运算 ...蓄水池抽样 二叉搜索树 记忆化
面向招聘的算法题技巧 算法题技巧 算法题(按照类型分类) ...蓄水池抽样 脑筋急转弯 记忆化 数学 几何 极小化极大 随机 扫描线算法 拒绝采样 ordered map map 了解更多欢迎关注微信公众号:科科人神