博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
水塘抽样算法
阅读量:6435 次
发布时间:2019-06-23

本文共 1929 字,大约阅读时间需要 6 分钟。

水塘抽样算法

水塘抽样算法是用于解决,对于一个未知长度的数据流进行随机采样的问题的。本文介绍几个算法及其变形。

说明:伪代码中S代表未知长度数据流,n为S的实际长度,S.CURRENT表示S当前值,S.NEXT代表S指针下移,R代表结果,k表示结果需要保留的个数。

简单抽样一个元素

Sample(S[1..n],R[1]) //s是未知长度的数据流  R[1]=S[1]          //取第一个值,初始化结果  count := 1         //计数器,记录当前为数据流中的第几位  while S has data    count++    j := random(0, 1)   //根据当前位置生成随机数[0,1)    if j < 1/count        R[1] = S.CURRENT    S.NEXT

证明:

一个元素的时候:被抽中的概率为1
两个元素的时候:第一个元素留下的概率为1-1/2,第二个元素留下的概率为 1/2
三个元素的时候:第一个元素留下的概率为(1-1/2)*(1-1/3)=1/3,第二个元素留下的概率为1/2*(1-1/3)=1/3,第三个元素留下的概率为1/3
以此类推,当判断到第i个元素时,第m(0<m<=i)个元素留下的概率为1/m*(1-1/(m+1))*(1-1/(m+2))...(1-1/(i))=1/i就可以保证所有元素的概率相等

算法R

ReservoirSample(S[1..n], R[1..k])  //使用前l个值初始化结果  for i = 1 to k      R[i] := S[i]  while S has next    i++    j := random(1, i)   //取1~i的随机数    if j <= k        R[j] := S[i]    //如果位置落在k之内则替换掉对应的R[j]

证明:

第m轮时,R中的每个元素被替换的概率为1/k*k/m=1/m,i能替换掉R中值的概率为k/m,所以到第i轮,第m(0<m<=i)个元素是k/m*(1-1/(m+1))*(1-1/(m+2))...*(1-1/i)=k/i

随机值排序水塘算法

ReservoirSample(S[1..?], R[1..k])  H = new max-priority-queue    //有序队列  while S has data    r = Random(0,1)    if H.Count < k      H.Insert(r, S.Current)    else      if H.Maximum > r        H.Extract-Max()        H.Insert(r, S.Current)    S.Next

该算法是对每个值进行随机值计算,并保留最大的k个随机值

带权重的随机值排序水塘算法

有些情况,采样的数据是有权重的,下面介绍几个带权重的水塘抽样算法

A-Res算法

ReservoirSample(S[1..?], R[1..k])  H = new min-priority-queue  while S has data    r = Random(0,1) ^ (1/S.Weight)  // 随机值取0-1随机值的1/weight的次方    if H.Count < k      H.Insert(r, S.Current)    else      if H.Minimum < r      //如果比队列中最小值大,则替换最小值        H.Extract-Min()         H.Insert(r, S.Current)    S.Next

该算法的随机值是使用了生成随机值的1/weight次方,可以增加高权重的随机值

分布式随机抽样

有些情况需要在分布式的情况下进行随机抽样,可以采用A-Res算法在分布式机器上运行,最后使用各机器上的值进行一起排序达到随机抽样的效果。

洗牌算法Fisher-Yates算法

一种需求是需要对所有的值进行乱序排序

shuffle(S[1..?])    for(i:= 1 .. n-1)        r:= random(0,i)     //[0,i]的随机值        swap(a[r],a[i])

JDK中的Collections.shuffle也是使用这个算法进行数组乱序的。

参考:

转载于:https://www.cnblogs.com/resentment/p/7435913.html

你可能感兴趣的文章
python常用内建模块(五)
查看>>
你为什么有那么多时间写博客?
查看>>
Excel 中使用VBA
查看>>
$.ajax同步请求会阻塞js进程
查看>>
Postman 网络调试工具
查看>>
Python教程6
查看>>
zabbix实现自动发现功能添加磁盘监控
查看>>
mysql8.0.14 安装
查看>>
1039. 到底买不买(20)
查看>>
android笔试题一
查看>>
【JavaEE企业应用实战学习记录】getConnListener
查看>>
了解轮询、长轮询、长连接、websocket
查看>>
bzoj2427[HAOI2010]软件安装
查看>>
WPF个人助手更新
查看>>
NLPIR技术助力中文智能数据挖掘
查看>>
python操作redis--------------数据库增删改查
查看>>
Android中仿IOS提示框的实现
查看>>
php初学第一课
查看>>
Windows下与Linux下编写socket程序的区别 《转载》
查看>>
java学习笔记 --- IO(3)
查看>>