您的位置:首页 > 其它

从数据流中随机选择m个数的算法

2013-09-13 04:07 204 查看
百度笔试题目:为分析用户行为,系统常需存储用户的一些query,但因query非常多,故系统不能全存,设系统每天只存m个query,现设计一个算法,对用户请求的query进行随机选择m个,请给一个方案,使得每个query被抽中的概率相等,并分析之,注意:不到最后一刻,并不知用户的总请求量。


方法一:

前m个直接存

对后面来的每个数据a[i](i > m),

随机生成一个(1..i)之前的随机数x,

若x<=m,确定a[i]被选中;再随机生成(1..m)之间的随机数y,用a[i]替换a[y].

证明思路:

1)对于处理前m个数,大家都被保存,概率都相等且为1

2)对于第i(i>m)个数a[i],被选中的概率是m/i;

对于之前保存的m个数,它们每一个上一次存活下来的概率是m/(i - 1)[从i-1个数中选m个数],本次存活的概率是1-(m/i)*(1/m)=1-1/i,所以到当前为止被选中概率是两者相乘=m/i

得证。


下面两个方法是从Hackbuteer1

/article/1358256.html

里面看来的,仅仅简化了一下证明流程。

方法二:

给每个元素随机生成一个固定区间(如[0,1])的权重。用一个大小为m的堆来选取权重较大的m个元素。


方法三:

前m个直接存

对后面来的每个数据a[i](i > m),

随机生成一个(1..i)之前的随机数x,

若x<=m,确定a[i]被选中,用a[i]替换a[x];

证明思路:

1)对于处理前m个数,大家都被保存,概率都相等且为1

2)对于第i(i>m)个数a[i],被选中的概率是m/i;

对于之前保存的m个数,它们每一个上一次存活下来的概率是m/(i - 1),本次存活的概率是1-1/i,所以到当前为止被选中概率是两者相乘=m/i

得证。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: