假设有一个源源不断吐出不同球的机器,只有装下10个球的袋子,每一个吐出的球,要么放入袋子,要么永远丢掉。如何做到机器吐出的每一个球之后,所有吐出的的球都等概率放入袋子中。
java
public class Reservoir {
public static class RandomBox{
private int[] bag;
private int N;
private int count;
public RandomBox(int capacity){
bag = new int[capacity];
this.N = capacity; // 袋子容量
count = 0;
}
private int rand(int max){
return (int)(Math.random()*max) + 1; // 返回1-max之间的随机数
}
public void add(int num){
count++;
if(count<=N){
bag[count-1] = num;
}else{
if(rand(num) <= N){
bag[rand(N)-1] = num;
}
}
}
public int[] choices(){
int[] ans = new int[N];
for (int i = 0; i < N; i++) {
ans[i] = bag[i];
}
return ans;
}
}
public static void main(String[] args) {
int all = 100; // 一共100个数
int choose = 10; // 选择10个放入袋子中
int testTimes = 50000; // 测试50000次
int[] counts = new int[all + 1];
for (int i = 0; i < testTimes; i++) {
RandomBox box = new RandomBox(choose);
for (int j = 1; j <= all; j++) {
box.add(j);
}
int[] ans = box.choices();
for (int j = 0; j < ans.length; j++) {
counts[ans[j]]++;
}
}
for (int i = 0; i < counts.length; i++) {
System.out.println(i+" times: "+counts[i]);
}
}
}