前天晚上卧谈时大家聊起来这个问题,讨论无果后上网搜寻证明过程,发现并没有什么有理有据让人信服的解释。昨天经过思考后又经过讨论,终于找到一个还算看的过去的证明。
问题
如何从0…n-1中随机选择m个整数,并且按照随机顺序输出最后的结果?如果列表中允许出现重复的整数,如何才能生成一个有序列表?如果既允许重复又需要按照随机顺序输出结果,那该怎样?
书上的答案
我们总是选择第一行,并使用二分之一的概率选择第二行,使用三分之一的概率选择第三行,以此类推。在该过程结束的时候,每一行具有相同的选中概率(1/n,其中n是文件中的总行数):
i=0
while more input lines
with probability 1.0/++i
choice = this input line
print choice
证明
按照伪代码,我们使用一个变量choice来存储选中的内容。
在读入第k行时,用这行的概率
1k+1
来判断这行是否被选中(因为k从0开始计数)。如果选中的话则用此行内容来填充choice。
【1】当n=1时,选中1的概率为1,此时choice中的内容为第一行的内容。
【2】当n=2时,选中2的概率为
12
,此时用2填充choice的概率即为
12
,所以此时choice中的内容为1的概率为
1−12
,即此时choice中为1和为2的概率皆为
12
。
【3】当n=3时,选中3的概率为
13
,此时用3填充choice的概率为
13
,所以此时chioce中的内容为3的概率为
13
,不为3的概率为
1−13
,当不为3的时候,此时情况退化为n=2的情形,即从3前面的内容中任选一个。而前面的内容出现概率相等。因1和2的内容出现的概率皆为
12
,故在此情况下1和2内容出现的概率为
12∗(1−13)
,即
13
。
……
【4】假设n=k时结论成立
【5】当n=k+1时,选中k的概率为
1k+1
,此时用k填充choice的概率为
1k+1
,所以此时chioce中的内容为k+1的概率为
1k+1
,不为k的概率为
1−1k+1
,当不为k+1的时候,此时情况退化为n=k的情形,即从k+1前面的内容中任选一个。而前面的内容出现概率相等。因前面的内容出现的概率皆为
1k
,故在此情况下前面内容出现的概率为
1k∗(1−1k+1)
,即
1k+1
。
在最后一步似乎还有部分不是很清楚的地方,欢迎指正