蓄水池采样原理

蓄水池采样算法在大数据集(长度未知)中实现等概率随机抽取样本。首先选择第一个对象,随后以1/(n+1)的概率选择下一个,确保每个对象被选中的概率为1/n。当需要抽取k个样本时,先取前k个,之后以k/(k+1)的概率选择新样本并可能替换已选中的一个,保证每个样本的选取概率为k/n。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、原理
蓄水池采样算法解决的是在给定但长度未知的大数据集中,随机等概率抽取一个数据。如果知道数据集的长度,可以用随机数rand()%n得到一个确切的随机位置,那么该位置的对象就是所求的对象,选中的概率是1/n。那长度未知该如何取?尤其是如果这个大数据集不能一次性放入内存中,蓄水池采样算法就非常有用了。

算法思路:我们总是选择第一个对象,以1/2的概率选择第二个,以1/3的概率选择第三个,以此类推,以1/m的概率选择第m个对象。当该过程结束时,每一个对象具有相同的选中概率,即1/n。

证明:第m个对象最终被选中的概率P=选择m的概率*其后面所有对象不被选择的概率,即
1m×(mm+1×m+1m+2×...×n−1n)=1n\frac{1}{m}\times(\frac{m}{m+1}\times\frac{m+1}{m+2}\times...\times\frac{n-1}{n})=\frac{1}{n}m1×(m+1

### 蓄水池抽样算法原理 蓄水池抽样算法是一种用于从流数据中随机抽样的算法。其核心思想在于,当面对一个非常大的数据集而内存无法承载全部数据时,可以仅保留一定数量的数据,并按特定概率对新到来的数据进行采样[^2]。 具体来说,对于每一个新的元素,会以 \( \frac{k}{i} \) 的概率决定是否将其加入到大小为 k 的样本集合(即所谓的“蓄水池”)之中;这里的 i 表示当前处理的是第几个元素,k 则表示希望抽取多少个样本。这种机制确保了即使不知道整个输入序列的具体长度也能均匀地从中选取样本[^3]。 #### 数学解释 为了理解为什么这种方法能够保证每个项目被选入的概率相等,考虑前 i 个项目出现在蓄水池里的可能性由两方面构成: - 在第 i+1 次选择之前已经在蓄水池里; - 不会在第 i+1 次的选择过程中被淘汰出去。 因此,通过这种方式构建起来的过程能使得所有项目的入选几率保持一致[^4]。 ### Java 实现案例 针对不同情况下的蓄水池抽样需求,以下是两个具体的Java实现版本: #### 当 `K>1` 时的完整版 ```java import java.util.Random; public class ReservoirSampling { private final int[] reservoir; private final Random random = new Random(); private int count = 0; public ReservoirSampling(int size) { this.reservoir = new int[size]; } public void addElement(int element) { if (count < reservoir.length) { reservoir[count++] = element; } else { int r = random.nextInt(count); if (r < reservoir.length) { reservoir[r] = element; } } count++; } @Override public String toString() { StringBuilder sb = new StringBuilder("["); for (int value : reservoir) { sb.append(value).append(", "); } return sb.substring(0, Math.max(sb.length() - 2, 0)) + "]"; } } ``` 这段代码展示了如何在一个未知规模的数据流上执行固定大小为 K 的简单无放回随机抽样操作。 #### LeetCode 应用实例 在实际应用中,蓄水池抽样也被广泛应用于解决各种编程挑战问题,比如 LeetCode 上编号为 398 和 382 的题目分别涉及到了基于权重的随机挑选以及链表结构上的节点随机访问等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值