**:
隨即抽樣問題:
要求從n個元素中隨機的抽取k個元素,其中n無法確定。
是在 《計算機程式設計與藝術》 中看到的這個題目,書中只給出了解法,沒給出證明。
解決方法是叫reservoir sampling (蓄水池抽樣)
init: a reservoir with the size: k
fori= k+1ton
m=random(1, i);
if( m < k)
swapthe mth valueandith 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
故證明成立
蓄水池抽樣演算法 隨機洗牌演算法
蓄水池抽樣演算法隨機演算法的一種,用來從 n 個樣本中隨機選擇 k 個樣本,其中 n 非常大 以至於 n 個樣本不能同時放入記憶體 或者 n 是乙個未知數。其時間複雜度為 o n 包含下列步驟 假設有一維陣列 s,長度未知,需要從中隨機選擇 k 個元素,陣列下標從 1 開始 偽 如下 init a ...
海量資料處理之蓄水池抽樣演算法
一 問題由來 這個題目的由來是在 程式設計珠璣 裡遇到的,故記錄一下。還可以這麼說,如何從二進位制檔案中等概率取整數?或者 在不知道檔案總行數的情況下,如何從檔案中隨機的抽取一行?這個題目說的有點不清楚實際上是 乙個二進位制檔案中有好多好多整數,你要隨機取出乙個。這個問題的難點就在於你開始不知道有多...
海量資料處理之蓄水池抽樣演算法
一 問題由來 這個題目的由來是在 程式設計珠璣 裡遇到的,故記錄一下。還可以這麼說,如何從二進位制檔案中等概率取整數?或者 在不知道檔案總行數的情況下,如何從檔案中隨機的抽取一行?這個題目說的有點不清楚實際上是 乙個二進位制檔案中有好多好多整數,你要隨機取出乙個。這個問題的難點就在於你開始不知道有多...