Skip to main content
added 182 characters in body
Source Link
JavaDeveloper
  • 8.4k
  • 29
  • 92
  • 159

Reservoir sampling implementation. Reservoir sampling is a family of randomized algorithms for randomly choosing a sample of k items from a list S containing n items, where n is either a very large or unknown number. If question is unclear let me know I will reply asap. Looking for code review, optimizations and best practice.

Reservoir sampling implementation. If question is unclear let me know I will reply asap. Looking for code review, optimizations and best practice.

Reservoir sampling implementation. Reservoir sampling is a family of randomized algorithms for randomly choosing a sample of k items from a list S containing n items, where n is either a very large or unknown number. If question is unclear let me know I will reply asap. Looking for code review, optimizations and best practice.

Source Link
JavaDeveloper
  • 8.4k
  • 29
  • 92
  • 159

Reservoir sampling

Reservoir sampling implementation. If question is unclear let me know I will reply asap. Looking for code review, optimizations and best practice.

public final class ReservoirSampling<T> {

    private final int k;

    /**
     * Constructs ReservoirSampling object with the input sample size.
     * 
     * @param k     the number of sample elements needed.
     * @throws IllegalArgumentException if k is not greater than 0.
     */
    public ReservoirSampling(int k) {
        if (k <= 0) {
            throw  new IllegalArgumentException("The k should be greater than zero");
        }
        this.k = k;
    };

    /**
     * Returns a list of random `k` samples from the input list.
     * 
     * @param   list of elements from which we chose the k samples from.
     * @return  the list containing k samples, chosen randomly.
     * @throws  NullPointerException if the input list is null.
     */
    public List<T> sample(List<T> list) {
        final List<T> samples = new ArrayList<T>(k);
        int count = 0;
        final Random random = new Random();
        for (T item : list) {
            if (count < k) {
                samples.add(item);
            } else {
                // http://en.wikipedia.org/wiki/Reservoir_sampling
                // In effect, for all i, the ith element of S is chosen to be included in the reservoir with probability
                // k/i.
                int randomPos = random.nextInt(count);
                if (randomPos < k) {
                    samples.set(randomPos, item);
                }
            }
            count++;
        }
        return samples;
    }
    
    
    
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
    
        ReservoirSampling<Integer> reservoirSampling = new ReservoirSampling<Integer>(3);
        System.out.print("Expected: 1 2 3, Actual: ");
        for (Integer i : reservoirSampling.sample(list)) {
            System.out.print(i + " ");
        }
        
        System.out.println();
        
        System.out.print("Expected: random output: ");
        list.add(4);
        list.add(5);
        list.add(6);
        for (Integer i : reservoirSampling.sample(list)) {
            System.out.print(i + " ");
        }
    }
}