另類算法題

1. 爲分析用戶行爲,系統常需存儲用戶的一些query,但因query非常多,故系統不能全存,設系統每天只存m個query,現設計一個算法,對用戶請求的query進行隨機選擇m個,請給一個方案,使得每個query被抽中的概率相等,並分析之,注意:不到最後一刻,並不知用戶的總請求量。(百度2011.10.16校園招聘會筆試題)

問題求解:
轉載: http://wansishuang.iteye.com/blog/443902
 
隨即抽樣問題:
 
    要求從N個元素中隨機的抽取k個元素,其中N無法確定。
 
  是在 《計算機程序設計與藝術》 中看到的這個題目,書中只給出瞭解法,沒給出證明。
 
  解決方法是叫Reservoir Sampling (蓄水池抽樣
 
 
                       Init : a reservoir with the size: k
 
                       for   i= k+1 to N
                              M=random(1, i);
                              if( M < k)
                                      SWAP the Mth value and ith value
                        end for
 
 
證明:
 
每次都是以 k/i 的概率來選擇
例: k=1000的話, 從1001開始作選擇,1001被選中的概率是1000/1001,1002被選中的概率是1000/1002,與我們直覺是相符的。
 
接下來證明:
     假設當前是i+1, 按照我們的規定,i+1這個元素被選中的概率是k/i+1,也即第 i+1 這個元素在蓄水池中出現的概率是k/i+1
     此時考慮前i個元素,如果前i個元素出現在蓄水池中的概率都是k/i+1的話,說明我們的算法是沒有問題的。
   
對這個問題可以用歸納法來證明:k < i <=N
   1.當i=k+1的時候,蓄水池的容量爲k,第k+1個元素被選擇的概率明顯爲k/(k+1), 此時前k個元素出現在蓄水池的概率爲 k/(k+1), 很明顯結論成立。
   2.假設當 j=i 的時候結論成立,此時以 k/i 的概率來選擇第i個元素,前i-1個元素出現在蓄水池的概率都爲k/i。  
      證明當j=i+1的情況:
      即需要證明當以 k/i+1 的概率來選擇第i+1個元素的時候,此時任一前i個元素出現在蓄水池的概率都爲k/(i+1).
前i個元素出現在蓄水池的概率有2部分組成, ①在第i+1次選擇前得出現在蓄水池中,②得保證第i+1次選擇的時候不被替換掉
       ①.由2知道在第i+1次選擇前,任一前i個元素出現在蓄水池的概率都爲k/i
       ②.考慮被替換的概率:  
首先要被替換得第 i+1 個元素被選中(不然不用替換了)概率爲 k/i+1,其次是因爲隨機替換的池子中k個元素中任意一個,所以不幸被替換的概率是 1/k,故
       前i個元素中任一被替換的概率 = k/(i+1) * 1/k = 1/i+1
       則沒有被替換的概率爲:   1 - 1/(i+1) = i/i+1
綜合① ②,通過乘法規則
得到前i個元素出現在蓄水池的概率爲 k/i * i/(i+1) = k/i+1
  故證明成立

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章