如何在不首先知道n的情况下随机选择n个对象中的一个?

时间:2011-09-01 07:16:58

标签: c algorithm

具体情况是,如果您事先不知道行数,您将如何阅读文本行,并选择并打印一个随机行?

是的,这是编程珍珠的问题,我感到困惑。

解决方案选择第一个元素,然后选择第二个概率为1/2,第三个选择1/3,依此类推。

算法:

i = 0
while more input lines
  with probability 1.0/++i
    choice = this input line
 print choice

假设最终选择是第3个元素,概率是 1 x 1/2 x 1/3 x 3/4 x ... x n-2 / n-1 x n-1 / n == 1 / 2n?但是1 / n应该是正确的。

4 个答案:

答案 0 :(得分:5)

您的算法是正确的,但分析不是。你可以通过归纳证明它。松散的:它当然适用于N = 1。如果它达到N-1,那么N会发生什么?选择第N个元素并覆盖最后一个选择的机会是1 / N - 好。它不是的机会是(N-1)/ N.在这种情况下,使用前一步骤的选择。但在那时,所有元素都有1 /(N-1)被选中的机会。现在是1 / N.好。

答案 1 :(得分:1)

您的计算错误:

假设最终选择是第3个元素,概率是 1 x 1/2 x 1/3 x 3/4 x ... x n-2 / n-1 x n-1 / n

真正的概率是:

(1 x 1/2 + 1 x 1/2)x 1/3 x 3/4 x ... x n-2 / n-1 x n-1 / n == 1 / n

既然你选择了2,或者你没有选择2(选择2的概率为1/2而不选择2的概率为1/2)

答案 2 :(得分:0)

阅读1 阅读2 任何一种可能性为50%,保留一种,丢弃一种。 阅读3 (我们应该有1和3或2和3)。 任何一条线的可能性为50%,丢弃另一条线。 在文件中一直保持50%的可能性,这将为您留下2行。 在任一线上取50/50并且你有一条随机线。 甚至整个文件的赔率都很高。

答案 3 :(得分:-1)

这不是真正随机的 - 因为您更有可能在文件的开头选择一行。您需要知道使其随机的行数。 (50%的时间你获得第一行!)