Category: algorithms | Component type: function |
template <class ForwardIterator, class OutputIterator, class Distance> OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, OutputIterator out, Distance n) template <class ForwardIterator, class OutputIterator, class Distance, class RandomNumberGenerator> OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, OutputIterator out, Distance n, RandomNumberGenerator& rand)
Random_sample copies m elements from [first, last) to [out, out + m), where m is min(last - first, n). The return value is out + m.
The first version uses an internal random number generator, and the second uses a Random Number Generator, a special kind of function object, that is explicitly passed as an argument.
int main() { const int N = 10; int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; random_sample_n(A, A+N, ostream_iterator<int>(cout, " "), 4); // The printed value might be 3 5 6 10, // or any of 209 other possibilities. }
[1] This is "Algorithm S" from section 3.4.2 of Knuth (D. E. Knuth, The Art of Computer Programming. Volume 2: Seminumerical Algorithms, second edition. Addison-Wesley, 1981). Knuth credits C. T. Fan, M. E. Muller, and I. Rezucha (1962) and T. G. Jones (1962). Note that there are N! / n! / (N - n)! ways of selecting a sample of n elements from a range of N elements. Random_sample_n yields uniformly distributed results; that is, the probability of selecting any particular element is n / N, and the probability of any particular sampling is n! * (N - n)! / N!.
[2] In contrast, the random_sample algorithm does not preserve relative ordering within the input range. The other major distinction between the two algorithms is that random_sample_n requires its input range to be Forward Iterators and only requires its output range to be Output Iterators, while random_sample only requires its input range to be Input Iterators and requires its output range to be Random Access Iterators.