算法--随机算法之水塘抽样(Reservoir sampling)以及算法证明

@[TOC](算法–随机算法之水塘抽样(Reservoir sampling)以及算法证明)
假设有这么一个问题,在人流穿梭的上海南京路的尽头,有电视台在采访,要求随机在一个小时内抽取一个人来进行采访.
首先分析这个问题:
1.你不能要求所有人都在这里等着,主要是电视台给的备用凳子不够只能保持一个人在凳子上.
2.不知道总数,人流是随机的不知道总数,所以不能得到总数N,然后通过1/N来得到相应的人.
3.怎么办?
最开始这个问题是在高纳德的<<计算机程序设计艺术>>一书中提出来的原本的问题是:
可否在一未知大小的集合中,随机取出一元素?
这个问题可以转换成上述问题.
当然这个问题还有很多种问法:
在不知道文件总行数的情况下,如何从文件中随机的抽取一行?
当内存无法加载全部数据时,如何从包含未知大小的数据流中随机选取k个数据,并且要保证每个数据被抽取到的概率相等?
等等.

然后既然存在问题那么我们就来分析问题.众所周知取得随机元素的最直观的方法就是算总数,打标签.利用rand(原理线性同余方法,不做过多介绍,非本节重点)系列函数取其中的一个数,命中则取之.
代码实现起来也非常简单.

//go源码实例-随机取10个字符中的一个
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	str := "qwertyuiop"
	rand.Seed(time.Now().Unix())
	key := rand.Int31()%10
	fmt.Printf(string(str[key]))
}

现在我们来说下位置情况下的算法
首先在再取到第一个元素的时候只有一个元素就是这个元素,概率为1/1.
再去到第二个元素的时候,随机产生1-2中间的一个数如果产生的数是2则取2,舍掉1.
再取第三个元素,随机产生1-3之间的一个数如果得到3则舍去之前的元素留下3.

取第n个元素的时候在1-n之间取随机数如果取到n则舍去之前的保留n.
直到所有的元素取尽.

算法证明:
数学归纳法
1.当n=1的时候
元素被取得的概率为1.符合条件
2.当n=2的时候.
2被取的概率为1/2.
1被取的概率为1*1/2 = 1/2.
3.当n=3时.
3被取的概率为1/3
1或2被取得概率为1/2(上一步算的的概率)*2/3(这一步随机到1或者2的概率)=1/3
4.假设当n=m时每个元素被取的概率是1/m
5.当n=m+1时
第m+1个元素取得概率是1/(m+1)
前m个元素被取的概率则是1/m*(m/(m+1))=1/(m+1)
6.证明完毕,命题成立

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值