【概率论】一种非常巧妙的随机抽样算法

博客围绕在集合{0,1,2,⋯,n−1}中随机抽取k个数(k≤n)的算法展开。给出了时间复杂度为O(n)的代码,通过数学归纳法和全概率公式,证明了该算法中每个元素被抽中的概率均为n/k。

假设我们现在要在集合{0,1,2,⋯ ,n−1}\{0,1,2,\cdots,n-1\}{0,1,2,,n1}中随机抽取kkk个数(k≤nk\le nkn)。显然每个元素被抽中的概率均为kn\frac{k}{n}nkC++代码如下:

vector<int> sample_integers(int n, int k = 3)
	// 在{0, 1, 2, ..., n - 1}中等可能地抽取k个元素
{
    vector<int> result;
    int i = 0;
    for(; n > 0; ++i, --n)
    {
        if(gen() % n < k) // 这个i被选中的几率是k/n
        {
            --k;
            result.push_back(i);
        }
    }
    return result;
}

时间复杂度为O(n)O(n)O(n)。要理解这种算法的正确性,我们只需证明每个元素被抽中的几率都是kn\frac{k}{n}nk。又因为数学归纳法,我们只需证明第一个元素被抽中的概率等于后面的元素被抽中的概率。

显然,抽中第一个元素000的概率是kn\frac{k}{n}nk。如果第一个元素被抽中了,那么后面的每个元素被抽中的概率是k−1n−1\frac{k-1}{n-1}n1k1;如果第一个元素没有被抽中,后面的每个元素被抽中的概率是kn−1\frac{k}{n-1}n1k。根据全概率公式,后面的每个元素被抽中的概率是P{后面的某个被抽中抽}=P{后面的某个被抽中抽∣第一个元素被抽中}P{第一个元素被抽中}+P{后面的某个被抽中抽∣第一个元素没有被抽中}P{第一个元素没有被抽中}=k−1n−1kn+kn−1n−kk=kn−1k−1n+kn−1n−kn=kn−1(k−1n+n−kn)=kn−1n−1n=kn\begin{aligned} P\{\text{后面的某个被抽中抽}\}&=P\{\text{后面的某个被抽中抽}|\text{第一个元素被抽中}\}P\{\text{第一个元素被抽中}\}\\&\qquad+P\{\text{后面的某个被抽中抽}|\text{第一个元素没有被抽中}\}P\{\text{第一个元素没有被抽中}\}\\ &=\frac{k-1}{n-1}\frac{k}{n}+\frac{k}{n-1}\frac{n-k}{k}\\ &=\frac{k}{n-1}\frac{k-1}{n}+\frac{k}{n-1}\frac{n-k}{n}\\ &=\frac{k}{n-1}\left(\frac{k-1}{n}+\frac{n-k}{n}\right)\\ &=\frac{k}{n-1}\frac{n-1}{n}\\ &=\frac{k}{n} \end{aligned}P{后面的某个被抽中抽}=P{后面的某个被抽中抽第一个元素被抽中}P{第一个元素被抽中}+P{后面的某个被抽中抽第一个元素没有被抽中}P{第一个元素没有被抽中}=n1k1nk+n1kknk=n1knk1+n1knnk=n1k(nk1+nnk)=n1knn1=nk这样就证明了抽中每个元素的概率均为kn\frac{k}{n}nk

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值