蓄水池抽样算法(reservoir sampling)

蓄水池抽样算法(reservoir sampling)

场景:在长度未知的数据流中,等概率地采样一定数量的数据。即,数据量N未知,若要求采样k个数据,采样概率保证 k N frac{k}{N} Nk/span>

要求:只遍历一遍数据,空间复杂度: O ( N ) O(N) O(N)

内容提要:算法主要思想、证明、LeetCode真题、Java源码。

文章目录

  • 蓄水池抽样算法(reservoir sampling)
    • 证明
      • K=1时
      • K>1时
    • K>1时,蓄水池抽样算法JAVA完整版
    • k=0时,蓄水池抽样算法JAVA完整版
    • LeetCode原题
      • [398. 随机数索引](https://leetcode-cn.com/problems/random-pick-index/)
      • [382. 链表随机节点](https://leetcode-cn.com/problems/linked-list-random-node/)
    • 埋个坑:分布式蓄水池抽样算法
    • 埋个坑2:

1、申请一个长度为K的数组A保存抽样,数组A相当于容量为K的蓄水池。
2、保存首先接收到的K个元素
3、当接收到第i个新元素t时,以k/i的概率随机替换A中的元素(即生成[1,i]间随机数j,若j<=k,则以t替换A[j])

证明

K=1时

数据流: x 1 , x 2 , , x i , x i + 1 , , x N 1 , x N x_1, x_2, cdots, x_i, x_{i+1}, cdots, x_{N-1}, x_N x1/span>,x2/span>,/span>,xi/span>,xi+1/span>,/span>,xN/span>1/span>,xN/span>

K=1时,相当于要在N个数据流中选择一个数据,此时假设数据的增长下标为i,i从1开始,当i=1时,随机选择一个数据的概率P为1;当i=2时,P为1/2;当i=3时,P为1/3。并且,不论i等于几,第一个数取到的概率总是 1 i frac{1}{i} i1/span>。当这个过过程结束时,每一个对象都有相同的被选概率 1 n frac{1}{n} n1/span>

证明:

i i i个被选中概率=选择第 i i i个对象的概率 × times × i i i个对象到第 n n n个对象没有被选择的概率

蓄水池抽样算法(reservoir sampling)

K>1时

数据流: x 1 , x 2 , , x i , x i + 1 , , x N 1 , x N x_1, x_2, cdots, x_i, x_{i+1}, cdots, x_{N-1}, x_N x1/span>,x2/span>,/span>,xi/span>,xi+1/span>,/span>,xN/span>1/span>,xN/span>

蓄水池: x 1 , x 2 , , x i , x i + 1 , , x K 1 , x K x_1, x_2, cdots, x_i, x_{i+1}, cdots, x_{K-1}, x_K x1/span>,x2/span>,/span>,xi/span>,xi+1/span>,/span>,xK/span>1/span>,xK/span>

问题就转化为,保证数据出现在蓄水池中的概率为 K N frac{K}{N} NK/span>

当K大于1时,要在N个数据流中选择K个数据,保证每一个数据被选择的概率相同: K N frac{K}{N} NK/span>

  • 第一种情况:当N小于K时,取每一个对象的概率都相同,每一个都会被取到,所以为1;

  • 第二种情况:当N大于K时,需要分步完成:

    • 第1步,先将蓄水池装满:

    • 第2步,当蓄水池装满之后,我们以第 i i i个对象 x i x_i x

      声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐