“编程珍珠”:从序列中抽取m个元素

时间:2012-07-29 05:26:26

标签: algorithm sampling

来自编程珍珠Column 12: A Sample Problem

  

输入包含两个整数 m n ,其中 m < 名词的。输出是    0..n-1 范围内的 m 随机整数的排序列表,其中没有   整数不止一次出现。对于概率增益,我们希望a   排序选择没有替换,其中每个选择发生   概率相等。

作者提供了一个解决方案:

initialize set S to empty
size = 0
while size < m do
    t = bigrand() % n
    if t is not in S
        insert t into S
        size++
print the elements of S in sorted order

在上面的伪代码中,bigrand()是一个函数返回一个大的随机整数(远大于 m n )。

有人可以帮我证明上述算法的正确性吗?

根据我的理解,每个输出的概率应为1 / C( n m )。 如何证明上述算法可以保证输出的概率为1 / C( n m )?

1 个答案:

答案 0 :(得分:1)

此算法产生的每个解决方案都有效。

有多少解决方案? 直到最后一行(排序)是n*(n-1)*(n-2)*..*(n-m)不同的排列或
n!/(n-m)!,每个结果都有相同的概率

当您排序时,可以通过m减少可能的解决方案数量。

因此可能的输出数量为n!/((n-m)!*m!),这就是您所要求的。

n!/((n-m)!m!) = C(n,m)