線性同餘法是一種使用很廣泛的偽隨機數生成器演算法:
r(n+1)=(a * r(n) + c) mod m; // 一般選取互質的a、c、m,而且m一般比較大
簡而言之,線性同餘法就是將當前的偽隨機數值乘以a再加上c,然後將除以m得到的餘數作為下乙個偽隨機數。
fisheryates洗牌演算法:
1. 初始化原始陣列和新陣列,原始陣列長度為n(已知);
2.從還沒處理的陣列(假如還剩k個)中,隨機產生乙個[0, k)之間的數字p(假設陣列從0開始);
3.把第p個數取出與第k個數交換;
4. 重複步驟2和3直到數字全部取完;
5. 從步驟3取出的數字序列便是乙個打亂了的數列。
下面證明其隨機性,即每個元素被放置在新陣列中的第i個位置是1/n(假設陣列大小是n)。乙個元素m被放入第i個位置的概率p = 前i-1個位置選擇元素時沒有選中m的概率 * 第i個位置選中m的概率,即:
}蓄水池抽樣(reservoir sampling )是乙個很有趣的問題,它能夠在o(n)時間內對n個資料進行等概率隨機抽取,例如:從1000個資料中等概率隨機抽取出100個。另外,如果資料集合的量特別大或者還在增長(相當於未知資料集合總量),該演算法依然可以等概率抽樣。
【解法】:每次以1/m的概率選擇是否將第m個數放入蓄水池。
【證明】:第m個數最終被選擇的概率 = 選擇第m個數*後面的數都不被選擇,即p=1
m∗[(
1−1m
+1)∗
(1−1
m+2)
∗...
∗(1−
1n)]
=1np=\frac 1m *[(1-\frac 1)*(1-\frac 1)*...*(1-\frac 1)]=\frac 1
p=m1∗
[(1−
m+11
)∗(
1−m+
21)
∗...
∗(1−
n1)
]=n1
【解法】:每次以k/m的概率選擇是否將第m個數放入蓄水池。
【證明】:第m個數最終被選擇的概率 = 選擇第m個數*(後面的數都不被選擇+後面的數被選擇但是不替換第m個數),即p=k
參考:
蓄水池抽樣演算法 隨機洗牌演算法
蓄水池抽樣演算法隨機演算法的一種,用來從 n 個樣本中隨機選擇 k 個樣本,其中 n 非常大 以至於 n 個樣本不能同時放入記憶體 或者 n 是乙個未知數。其時間複雜度為 o n 包含下列步驟 假設有一維陣列 s,長度未知,需要從中隨機選擇 k 個元素,陣列下標從 1 開始 偽 如下 init a ...
演算法 蓄水池抽樣
例題 有乙個機器按自然數序列的方式吐出球,1號球,2號球.現有乙個袋子,袋子裡最多只能裝下k個球,並且除袋子以外沒有更多的空間,球扔掉不能放回。設計一種選擇方式,使得當機器吐出第n號球時,袋子中的球數是k個,同時可以保證從1號球到n號球中的每乙個被選中進袋子的概率都是k n。具體例子 有乙個只能裝下...
蓄水池抽樣演算法
給你乙個長度為n的鍊錶。n很大,但你不知道n有多大。你的任務是從這n個元素中隨機取出k個元素。你只能遍歷這個鍊錶一次。你的演算法必須保證取出的元素恰好有k個,且它們是完全隨機的 出現概率均等 蓄水池抽樣演算法 該演算法是針對從乙個序列中隨機抽取不重複的k個數,保證每個數被抽取到的概率為k n這個問題...