Skip to content

Repository files navigation

Sampling without replacement

The problem of sampling without replacement: given integers n, k such that 0 ≤ kn, return kdistinct nonnegative integers < n, choosing at random such that every possible result is equally likely. One way to get a precise understanding of the problem is to look at the simplest algorithm for solving it, via these Python or C++ implementations.

Here, I propose an algorithm I call "Cardchoose" for this problem which as far as I know is novel, and which in C++ outperforms all other solutions to either problem for most (n, k) inputs. The only data structure used is the output vector, so no extra memory is needed; it runs in O(k log k) time. I've implemented this and other algorithms in C++ and Python to compare their performance.

In my C++ tests, cardchoose outperforms rejectionsample, floydf2, and hsel for all values of n and k. quadraticreject is best where k < 100 or so, and select and iterativechoose perform well when k/n is large. cardchoose always performs within an acceptable factor of other algorithms.

defsorted_choose(n, k):
"k distinct integers 0 <= x < n, sorted"t=n-k+1d= [None] *kforiinrange(k):
r=random.randrange(t+i)
ifr<t:
d[i] =relse:
d[i] =d[r-t]
d.sort()
foriinrange(k):
d[i] +=ireturnd

graph

This is not an officially supported Google product.

About

Sampling without replacement algorithms

Resources

Contributing

Stars

16 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages