蓄水池算法
引子
Q: 从长度为N的数据中随机等概抽出1条数据。
A: 第j个元素以概率决定保留

问题
从长度为N的数据中随机抽出长度为K的数据,即每个元素被选中的概率都为
做法
- 初始化:依次取出前
K个元素; - 此后,第
j个元素以概率决定保留
证明

public class ReservoirSamplingTest { private int[] pool; // 所有数据 private final int N = 100000; // 数据规模 private Random random = new Random(); @Before public void setUp() throws Exception { // 初始化 pool = new int[N]; for (int i = 0; i < N; i++) { pool[i] = i; } } private int[] sampling(int K) { int[] result = new int[K]; for (int i = 0; i < K; i++) { // 前 K 个元素直接放入数组中 result[i] = pool[i]; } for (int i = K; i < N; i++) { // K + 1 个元素开始进行概率采样 int r = random.nextInt(i + 1); // 这里其实就是k/j的体现 if (r < K) { result[r] = pool[i]; } } return result; } @Test public void test() throws Exception { for (int i : sampling(100)) { System.out.println(i); } } }

浙公网安备 33010602011771号