蓄水池算法

169 阅读1分钟

在一个未知的池子里选1个数字,让他们被选择概率一致。 假设n的时候,前n个数字被选择的概率都是1n1n 当为n+1时候,当前n+1这个数,我们选择的概率是1n+11n+1,其余数字的概率是nn+1nn+1,那么一共有n个数字的概率是1n1n 所以 n∗1n∗1n+1=1n+1 n∗1n∗1n+1=1n+1 具体算法代码使用的方式是i = random.randint(0,n) < k则选择。 这里其实就是在[0,n]区间内选择了是否比k大的数字。

import random
def demo(lst,k):
    ret_lst = lst[0:k]
    for i in range(k,len(lst)):
        m = random.randint(0,i)
        if m < k:
            ret_lst[m] = lst[i]
    return ret_lst


def main():
    iters = 10000
    num = 10
    cnt_lst = [0 for i in range(num)]
    for i in range(iters):
        lst = [i for i in range(num)]
        ret_lst = demo(lst,3)
        for x in ret_lst:
            cnt_lst[x] += 1 
    pro_lst = list(map(lambda x :x/iters,cnt_lst))
    print(cnt_lst)
    print(pro_lst)
if __name__ == '__main__':
    main()

示例:

[3083, 2982, 3048, 2966, 3032, 2930, 2907, 3094, 2958, 3000]
[0.3083, 0.2982, 0.3048, 0.2966, 0.3032, 0.293, 0.2907, 0.3094, 0.2958, 0.3]