Algorithm to select a single, random combination of values?

Robert Floyd invented a sampling algorithm for just such situations. It’s generally superior to shuffling then grabbing the first x elements since it doesn’t require O(y) storage. As originally written it assumes values from 1..N, but it’s trivial to produce 0..N and/or use non-contiguous values by simply treating the values it produces as subscripts into a vector/array/whatever.

In pseuocode, the algorithm runs like this (stealing from Jon Bentley’s Programming Pearls column “A sample of Brilliance”).

initialize set S to empty
for J := N-M + 1 to N do
    T := RandInt(1, J)
    if T is not in S then
        insert T in S
    else
        insert J in S

That last bit (inserting J if T is already in S) is the tricky part. The bottom line is that it assures the correct mathematical probability of inserting J so that it produces unbiased results.

It’s O(x)1 and O(1) with regard to y, O(x) storage.

Note that, in accordance with the tag in the question, the algorithm only guarantees equal probability of each element occuring in the result, not of their relative order in it.


1O(x2) in the worst case for the hash map involved which can be neglected since it’s a virtually nonexistent pathological case where all the values have the same hash

Leave a Comment