Reservior Sampling (蓄水池抽样算法)

Reservior Sampling (蓄水池抽样算法)


1. 蓄水池抽样问题描述

  Reservoir sampling is a family of randomized algorithms for randomly choosing a sample of k items from a list S containing n items, where n is either a very large or unknown number. Typically n is large enough that the list doesn’t fit into main memory.
  蓄水池抽样问题是,从一个长度为n的流中随机选取k个元素,使得n个元素中的每个元素都以相同的概率被采样到,通常情况下n是一个未知的很大的数目,而且无法将其载入主存中。


2. 蓄水池抽样的解法

  在Dictionary of Algorithms and Data Structures中该问题的定义与解法如下:

  • Definition: Randomly select k items from a stream of items of unknown length.
  • Solution: Save the first k items in an array of size k. For each item j, j > k, choose a random integer M from 1 to j (inclusive). If M ≤ k, replace item M of the array with item j.

该问题的解法一般被称为 Algorithm R 由 Jeffrey Vitter 在其论文“Random sampling with a reservoir” 中提出,其伪代码如下所示:

(*
  S has items to sample, R will contain the result
 *)
ReservoirSample(S[1..n], R[1..k])
  // fill the reservoir array
  for i = 1 to k
      R[i] := S[i]

  // replace elements with gradually decreasing probability
  for i = k+1 to n
    j := random(1, i)   // important: inclusive range
    if j <= k
        R[j] := S[i]

3. Algorithm R 算法的数学证明

采用数学归纳法进行证明:假设我们要从 n 个元素中随机抽取 k 个元素( 0kn ),使得每个元素被采样的概率等于 kn

kmn
m=k 时,从 m 个元素随机采样 k 个,则 k 个元素均被采样到,因此每个元素被采样的概率为 km=1.0 ,初始条件满足。
假设 n=m>k 时假设成立,即每个元素被采样的概率等于 km ,则 n=m+1 时有:
对于第 m+1 个元素,其被抽样的概率为 km+1
对于在当前容积为 k 的蓄水池中的元素,其被抽样的概率由两部分组成:
1) 如果第 m+1 个元素未被采样,则此部分的概率为 km(1km+1)
2) 如果第 m+1 个元素被采样,但是在蓄水池中的元素未被第 m+1 个元素替换,则此部分概率为: kmkm+1k1k
因此将1)和2)相加即可得到蓄水池中的元素被采样的概率为:

km(1km+1)+kmkm+1k1k

=km(m+1km+1+k1m+1)

=kmmm+1

=km+1

因此, n=m+1 , 时假设成立,所以根据归纳法可知结论对一切 nk 成立。


4. leetcode 刷题

  • 382. Linked List Random Node

你可能感兴趣的:(学习)