水塘抽样解析(详细)

水塘抽样解析

什么是水塘抽样(参考百度百科

水塘抽样是一系列的随机算法,其目的在于从包含n个项目的集合S中选取k个样本,其中n为一很大或未知的数量,尤其适用于不能把所有n个项目都存放到内存的情况。最常见例子为[Jeffrey Vitter](https://baike.baidu.com/item/Jeffrey Vitter)在其论文中所提及的算法R

算法步骤(参考百度百科)

参照Dictionaryof Algorithms and Data Structures所载的O(n)算法,包含以下步骤(假设阵列S以0开始标示): [1]

从S中抽取首k项放入「水塘」中

对于每一个S[j]项(j ≥ k):

随机产生一个范围从0到j的整数r

若 r < k 则把水塘中的第r项换成S[j]项

实现

//假设集合的总长度是n 需要从n中随机取k个

public String[] random(int k,String[] ns){
 
    String[] rs = new String[k];
     Random random = new Random();
    for(int i=0,len=ns.length;i++){
        //首先 先将前k最为结果保存
        if(i<k){
            rs[i] = ns[i];
        }else{
            //第k+1次,取随机数,随机数<k,就将随机数所对应的值替换成当前值
            int tmp = random.nextInt(i);
            if(tmp < k){
                rs[tmp] = ns[i];
            }
        }
    }
    return rs;
}

验证

我们可以看到,第n行被抽中的概率Pn为k/n,那么还需要算上后续的n+1-N次不被覆盖的概率即下面的算法。其中Pj表示第**j(n+1…N)**次抽中的概率为k/j,那么覆盖第n次即j-1的概率为Pj/k,最终得到k/N,第n行的概率至于k和N相关,即等概率。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值