• 水库抽样


    需求分析

    有一个题库,包含10000道题.对于每个学生,生成一套试卷,试卷包含10道题.

    离线随机抽样

    从a[N]中选取k个元素

    for i in range(0,k):
    	swap(a[i],a[random.nextint(i,N)])
    

    最终所得a[0~k]即为所求,这样抽样会打乱原数组的顺序,不过没有关系(对于离线随机抽样,原始数组混乱也没关系).只要保证每一时刻只有一个线程在"操作"这个题库数组即可.


    复杂度分析:O(k)的时间复杂度,O(N)的空间复杂度

    在线随机抽样

    一个流数组,它有N个元素,从中随机抽取k个元素,每个元素只能读取一次.

    int a[k]
    for i in range(0,k):
    	cin>>a[i]
    for i in range(k,N):
    	cin>>x
    	p=random.nextInt(0,i)
    	if p<k:
    		a[p]=x
    

    以7选3为例,对于整个流中的第一个元素,它被选中的概率为1*(3/4)*(4/5)*(5/6)*(6/7)=3/7,3/4表示第4个元素来临时,第四个元素有1/4的概率替换掉第一个元素,所以就有3/4的概率不被第四个元素替换掉。同理,不被第五个元素替换掉的概率为4/5,不被第六个元素替换掉的概率为5/6......
    对于流中的第4个元素,它进入a数组的概率为3/4,它最终留在a数组中的概率为(3/4)*(4/5)*(5/6)*(6/7)=3/7

    上面这种证明不够完善,需要说明一件事:
    第一个元素被选择的概率为3/7,定义为事件p1
    第二个元素被选择的概率为3/7,定义为事件p2
    第三个元素被选择的概率为3/7,定义为事件p3
    第四个元素被选择的概率为3/7,定义为事件p4
    第五个元素被选择的概率为3/7,定义为事件p5
    ......
    p1,p2,p3,p4......两两互相独立,任意组合C(N,K)出现的概率都等于(K/N)^K

    不说明事件独立性这一点,是不完善的证明。

    复杂度分析:因为是流式处理,所以整个数组没有完全读入内存,空间复杂度为O(k).时间复杂度为O(N),因为要遍历整个数组一次.
    离线和在线时间复杂度和空间复杂度正好颠倒,可以说离线算法是以空间换时间,在线算法是以时间换空间.

  • 相关阅读:
    laravel路由和MVC
    laravel目录介绍
    laravel下载安装
    Mac 程序员的十种武器
    Python中列表的copy方法
    Ubuntu 安装vim失败解决
    Linux userAdd 增加用户如果没有配置文件情况解决
    Ubuntu 软件管理
    awk工具详解
    httpsClient
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/6130899.html
Copyright © 2020-2023  润新知