不知道蓄水池抽样算法?那就进来看看吧~

力扣中关于蓄水池抽样问题官方标签是 2 道,根据个人作题状况来看,可能有三四道。比重算是比较低的,你们能够根据本身的实际状况选择性掌握。node

蓄水池抽样的算法思惟很巧妙,代码简单且容易理解,就算不掌握它,做为了解也是很不错的。算法

问题描述

给出一个数据流,咱们须要在此数据流中随机选取 k 个数。因为这个数据流的长度很大,所以须要边遍历边处理,而不能将其一次性所有加载到内存。数组

请写出一个随机选择算法,使得数据流中全部数据被等几率选中。app

这种问题的表达形式有不少。好比让你随机从一个矩形中抽取 k 个点,随机从一个单词列表中抽取 k 个单词等等,要求你等几率随机抽取。无论描述怎么变,其本质上都是同样的。今天咱们就来看看如何作这种题。dom

算法描述

这个算法叫蓄水池抽样算法(reservoid sampling)。code

其基本思路是:索引

  • 构建一个大小为 k 的数组,将数据流的前 k 个元素放入数组中。
  • 对数据流的前 k 个数不进行任何处理。
  • 从数据流的第 k + 1 个数开始,在 [1, i] 之间选一个数 rand,其中 i 表示当前是第几个数。
  • 若是 rand 大于等于 k 什么都不作
  • 若是 rand 小于 k, 将 rand 和 i 交换,也就是说选择当前的数代替已经被选中的数(备胎)。
  • 最终返回幸存的备胎便可

这种算法的核心在于先以某一种几率选取数,并在后续过程以另外一种几率换掉以前已经被选中的数。所以实际上每一个数被最终选中的几率都是被选中的几率 * 不被替换的几率内存

伪代码:leetcode

伪代码参考的某一本算法书,并略有修改。
Init : a reservoir with the size: k
for i= k+1 to N
    if(random(1, i) < k) {
        SWAP the Mth value and ith value
    }

这样能够保证被选择的数是等几率的吗?答案是确定的。get

  • 当 i <= k ,i 被选中的几率是 1。
  • 到第 k + 1 个数时,第 k + 1 个数被选中的几率(走进上面的 if 分支的几率)是 $\frac{k}{k+1}$,到第 k + 2 个数时,第 k + 2 个数被选中的几率(走进上面的 if 分支的几率)是 $\frac{k}{k+2}$,以此类推。那么第 n 个数被选中的几率就是 $\frac{k}{n}$
  • 上面分析了被选中的几率,接下来分析不被替换的几率。到第 k + 1 个数时,前 k 个数被替换的几率是 $\frac{1}{k}$。到前 k + 2 个数时,第 k + 2 个数被替换的几率是 $\frac{1}{k}$,以此类推。也就是说全部的被替换的几率都是 $\frac{1}{k}$。知道了被替换的几率,那么不被替换的几率其实就是 1 - 被替换的几率。

所以对于前 k 个数,最终被选择的几率都是 1 * 不被 k + 1 替换的几率 * 不被 k + 2 替换的几率 * ... 不被 n 替换的几率,即 1 * (1 - 被 k + 1 替换的几率) * (1 - 被 k + 2 替换的几率) * ... (1 - 被 n 替换的几率),即 $1 \times (1 - \frac{k}{k+1} \times \frac{1}{k}) \times (1 - \frac{k}{k+2} \times \frac{1}{k}) \times ... \times (1 - \frac{k}{n} \times \frac{1}{k}) = \frac{k}{n} $。

对于 第 i (i > k) 个数,最终被选择的几率是 第 i 步被选中的几率 * 不被第 i + 1 步替换的几率 * ... * 不被第 n 步被替换的几率, 即 $\frac{k}{k+1} \times (1 - \frac{k}{k+2} \times \frac{1}{k}) \times ... \times (1 - \frac{k}{n} \times \frac{1}{k}) = \frac{k}{n} $。

总之,无论是哪一个数,被选中的几率都是 $\frac{k}{n}$,知足几率相等的需求。

相关题目

总结

蓄水池抽样算法核心代码很是简单。可是却不容易想到,尤为是以前没见过的状况下。其核心点在于每一个数被最终选中的几率都是被选中的几率 * 不被替换的几率。因而咱们能够采起某一种动态手段,使得每一轮都有几率选中和替换一些数字。 上面咱们有给出了几率相等的证实过程,你们不妨本身尝试证实一下。以后结合文末的相关题目练习一下,效果会更好。

相关文章
相关标签/搜索