描述
该算法可用于从数据流中随机抽取指定数量的样本。
假设目标样本数量为 n,参与抽样的数量为 i。
蓄水池容量为 n,参与抽样的数量为 i
每接收一个样本,不断计算抽样结果:
- i < n 时,直接将样本留在蓄水池
- i >= n 时,随机从 参与抽样的样本中选择一个,如果超过蓄水池水位,则淘汰新进来的元素,否则以新进来的元素替换刚刚选中的那个样本
最终每个元素的留下概率为:
- i <= n 时,概率为 1
- i > n 时,概率为 n i \frac {n} {i} in
Java基本实现
提供基本实现思路,实际落地适当改造
蓄水池模型
public class Award {
/**
* 中奖人数组
*/
private int[] persons;
/**
* 参与人数
*/
private int count;
public Award(int award) {
this.persons = new int[award];
}
/**
* 参与抽奖
* @param id
*/
public void join(int id) {
if (count < persons.length) {
persons[count] = id;
count++;
} else {
count++;
int result = (int) (Math.random() * count);
if (result <= persons.length - 1) {
persons[result] = id;
}
}
}
public int[] getPersons() {
return persons;
}
}
参与抽样
- 模拟抽样(实际开发中,更适合外部数据来一个计算一个抽样结果)
抽样目标10个,样本数 10000000 个
Award award = new Award(10);
for (int i = 0; i < 10000000; i++) {
award.join(i);
}
这个系列为个人日常分享,仅作参考。
各种解决方案欢迎留言。
本文介绍了蓄水池抽样算法在数据流中的应用,包括原理、Java的基本实现以及如何在模拟场景中使用,用于随机抽取指定数量的样本。作者提供了一个简单的Award类实例并指出这仅作参考,欢迎读者分享其他解决方案。
蓄水池抽样算法(可用于抽样,抽奖等场景)&spm=1001.2101.3001.5002&articleId=133323642&d=1&t=3&u=21633e832cfd4435b68424ed78d9d2f8)
1605

被折叠的 条评论
为什么被折叠?



