zoukankan      html  css  js  c++  java
  • 蓄水池算法介绍和证明[原创]

    蓄水池算法要解决的问题就是在不知道流入数据量多少的情况下,依旧可以随机从这些数中选取K个,乍一听好神奇,其实分析一下背后的概率知识,思想还是很简单的,相信看完我的介绍和证明,你也会觉得很简单。

    假设要求随机选择K个元素,假设一共流入的元素有n个。

      首先数组a[0...k-1]表示最后返回的结果,最开始流入的k个元素依次放入a[0...k-1]中;

      那么从第k+1到第n个元素每一次都有可能把数组a中的元素踢走换成自己,假设现在流入了第i个元素,搞个随机数生成器,pos=rand()%i,如果pos<k,那么就把这个元素放到pos这个位置上,把以前这个位置上的元素剔除。

      最后,返回数组a就可以了,就是概率相等的k个元素。

    下面来证明所有的元素都是等概率的:

    首先,来看第1~k个元素:

    最后存在的概率是:

    1*[k/(k+1)]*[(k+1)/(k+2)]*[(k+2)*(k+3)]*...*[(n-1)/n]=k/n

    来分析一下,前k个元素,以第一个举例,初始选中概率为1,后面每增加一个元素不能把第一个元素替换掉的概率依次是[k/(k+1)],[(k+1)/(k+2)],[(k+2)*(k+3)]。。。

    这样到最后一个元素,分子分母相约,得到第一个元素存在的概率是k/n;

    再看第k+1~n个元素:

    从第k+1开始,k+1<= i <=n,现在有i-1个元素,进来一个元素时选中它的概率是k/i,而后面的元素没有把它替换掉的概率是:

    [i/(i+1)],[(i+1)/(i+2)],[(i+2)*(i+3)] ... [(n-1)/n]

    最后得到概率是[k/i]*[i/(i+1)]*[(i+1)/(i+2)]*[(i+2)*(i+3)]* ... *[(n-1)/n]=k/n

    综上,得到蓄水池算法得到k个元素都是等概率的。

  • 相关阅读:
    leetcode5
    leetcode4
    maven笔记
    枚举使用笔记
    List遍历删除解决方案:遍历删除,迭代删除,removeIf
    java笔记(web部分)
    webview使用
    json数据格式+gson解析json问题总结
    android:layout_weight的简单使用
    欢迎界面效果
  • 原文地址:https://www.cnblogs.com/aboutblank/p/4800874.html
Copyright © 2011-2022 走看看