從數據流中隨機選擇m個數的算法

百度筆試題目:爲分析用戶行爲,系統常需存儲用戶的一些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

http://blog.csdn.net/hackbuteer1/article/details/7971328

裏面看來的,僅僅簡化了一下證明流程。

 

方法二:

給每個元素隨機生成一個固定區間(如[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
得證。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章