其他题目---蓄水池算法

来源:互联网 发布:网络维护费用明细 编辑:程序博客网 时间:2024/06/06 00:31

【题目】

  有一个机器按自然数顺序的方式吐出球(1号球、2号、3号…),你有一个袋子,袋子最多只能装下K个球,并且除此之外你没有更多的空间。设计一种选择方式,使得当机器吐出第N号球的时候(N > K),你袋子中球的个数是K个,同时保证从1号球到N号球中的每一个,被选进袋子的概率是K/N。

【基本思路】

  这道题的核心解法就是蓄水池算法。过程如下:
  1、将第1~k个球直接放入袋子
  2、处理第i号球时(i > k),以k/i的概率决定是否将第i号球放入袋子中。如果不决定放入袋子,直接扔掉第i号球;否则,在袋子中随机选择一个扔掉,然后放入第i号球
  3、重复步骤2直到 i == N

  证明:

  对于第i号球进袋子的分析分两部分:

  1、当1ik时,那么在选第k+1号球时,第i号球留在袋子中的概率是1。

  在选第k+1号球的时候,只有决定第k+1号球入袋,并且第i号球正好被随机选中的时候,第i号球才会被淘汰。所以第i号球被淘汰的概率是p=kk+11k,所以第i号球留下来的概率就是1p=kk+1。那么从第1号球到第K+1号球的过程中,第i号球最终留下来的概率是kk+1

  同理,在选第k+2号球的时候,第i号球被淘汰的概率是p=kk+21k,所以第i号球留下来的概率就是1p=k+1k+2。那么从第1号球到第K+2号球的过程中,第i号球最终留下来的概率是kk+1k+1k+2

  依次类推,在选第N号球的时候,从第1号球到第N号球的过程中,第i号球最终留下来的概率是kk+1k+1k+2...N1N=kN

  2、当k<i时,那么在选第i号球时,第i号球留在袋子中的概率是k/i。

  在选第i+1号球的时候,只有决定第i+1号球入袋,并且第i号球正好被随机选中的时候,第i号球才会被淘汰。所以第i号球被淘汰的概率是p=ki+11k=1i+1,所以第i号球留下来的概率就是1p=ii+1。那么从第i号球被选中到第i+1号球的过程中,第i号球最终留下来的概率是kiii+1

  同理,在选第i+2号球的时候,第i号球被淘汰的概率是p=ki+21k,所以第i号球留下来的概率就是1p=i+1i+2。那么从第i号球到第i+2号球的过程中,第i号球最终留下来的概率是kiii+1i+1i+2

  依次类推,在选第N号球的时候,从第i号球到第N号球的过程中,第i号球最终留下来的概率是kiii+1...N1N=kN

  所以,按照该方法,当吐出球数为N时,每一个球被选进袋子的概率都是K/N。

【代码实现】

#python3.5def getKNumRand(k, max):    def rand(max):        return int(random.random() * max) + 1    if k < 1 or max < 1:        return None    res = []    for i in range(k):        res.append(i+1)    for i in range(k+1, max+1):        if rand(i) <= k:            res[rand(k)-1] = i    return res
原创粉丝点击