排列 組合 蓄水池抽樣

2021-09-28 14:58:13 字數 3257 閱讀 5051

從 5個元素中取3個數排列。第一次取有5種情況,拿出乙個數後,第二次取有4種情況,第三次取有3中情況。所以5中取3的排列共有

5*(5-1)(5-2) = 60種情況,由 3個數的排列由32*1=6中。也就是每一種組合有6種排列。

所以中取三個數的組合為

5 ∗(

5−1)

∗(5−

2)3∗

(3−1

)(3−

2)=10

\frac = 10

3∗(3−1

)(3−

2)5∗

(5−1

)∗(5

−2)​

=10推廣到一般情況,從n個元素中取k個元素的組合個數,記作c(n,k),則有

c (n

,k)=

n∗(n

−1)∗

(n−2

)...

∗(n−

(k−2

))∗(

n−(k

−1))

k∗(k

−1)∗

(k−2

)...

∗3∗2

∗1

c(n,k) = \frac

c(n,k)

=k∗(

k−1)

∗(k−

2)..

.∗3∗

2∗1n

∗(n−

1)∗(

n−2)

...∗

(n−(

k−2)

)∗(n

−(k−

1))​

其中,含有某個元素m的組合個數,取出m後,還剩n-1個元素,從中要抽取另外k-1個元素,和m組成組合。所以c(n,k)個組合中含有某個確定元素m的組合個數為c(n-1,k-1),那麼對於n個元素取出k個元素,某個元素被抽中的概率

p =c

(n−1

,k−1

)c(n

,k)=

kn

p = \frac = \frac

p=c(n,

k)c(

n−1,

k−1)

​=nk

​123

456…

kk+1

…n-1

n使用均勻隨機數生成函式rand(),從n個元素中抽取k個元素。要求每個元素被抽中的概率符合k

n\frac

nk​為了便於理解,下面的說明違背了程式編寫的傳統,陣列索引不從0開始,而從1起始。

從第k+1個元素開始處理,

第k+1個元素,int index = rand()%(k+1) + 1; index的取值範圍是[1,k+1],如果 index 的取值在[1,k]上,則 把第k+1個元素與index位置的元素交換。這個事件發生的概率為kk+

1\frac

k+1k

​第k+2個元素,int index = rand()%(k+2) + 1; index的取值範圍是[1,k+2],如果 index 的取值在[1,k]上,則 把第k+2個元素與index位置的元素交換。這個事件發生的概率為kk+

2\frac

k+2k

​第k+3個元素,int index = rand()%(k+3) + 1; index的取值範圍是[1,k+3],如果 index 的取值在[1,k]上,則 把第k+3個元素與index位置的元素交換。這個事件發生的概率為kk+

3\frac

k+3k​…

…第n-1個元素,int index = rand()%(n-1) + 1; index的取值範圍是[1,n-1],如果 index 的取值在[1,k]上,則 把第n-1個元素與index位置的元素交換。這個事件發生的概率為kn−

1\frac

n−1k

​第n個元素,int index = rand()%(n) + 1; index的取值範圍是[1,n],如果 index 的取值在[1,k]上,則 把第n個元素與index位置的元素交換。這個事件發生的概率為k

n\frac

nk​

index12

3456

…kk+1…

n-1npkk+

1\frac

k+1k​kn−

1\frac

n−1k​kn−

2\frac

n−2k

​證明,經過這輪操作後,n個元素中每個元素在前k個的概率均符合要求,分兩種情況討論。

1,索引為m的元素,m<=k,想要在處理後仍然在前k個,必須滿足,所有的隨機生成int index全不為m,淘汰是個單向過程,一旦被從前k個剔除,就無法回到前k個中。所以

p =k

k+1∗

k+1k

+2∗k

+2k+

3∗n−

2n−1

∗n−1

n=kn

p = \frac *\frac *\frac *\frac * \frac = \frac

p=k+1k

​∗k+

2k+1

​∗k+

3k+2

​∗n−

1n−2

​∗nn

−1​=

nk​

2,索引為m的元素,m>k,在處理前不在前k個元素,所以它被抽中必須要滿足處理到它時的計算出的index值小於等於k,這樣m元素就被交換到了前k個,且在處理後面的元素是,m元素沒被交換出去。

p =k

m∗mm

+1∗m

+1m+

2∗n−

2n−1

∗n−1

n=kn

p = \frac *\frac *\frac *\frac * \frac = \frac

p=mk​∗

m+1m

​∗m+

2m+1

​∗n−

1n−2

​∗nn

−1​=

nk​證的,n中某個任意元素經過這個操作,位置在k前個的概率等於,n個元素取出k個元素,某個元素被抽中的概率。

#include #include using namespace std;

const int n = 1000;

const int k = 100;

int main(int argc, char *ar**)

for(int i=k;i}

for(int i=0;ireturn 0;

}

蓄水池 抽樣

蓄水池抽樣問題描述的是,在乙個無窮盡的樣本中,要求隨即抽取一些樣本,這些樣本被抽取到的概率必須保持一致。乙個蓄水池就可以理解為無窮大的樣本空間。解決方案就是蓄水庫抽樣 reservoid sampling 主要思想就是保持乙個集合,作為蓄水池,依次遍歷所有資料的時候以一定概率替換這個蓄水池中的數字。...

蓄水池抽樣

題目 要求從n個元素中隨機的抽取k個元素,其中n無法確定 解法 首先選擇n中的前k個數加入 蓄水池 中,然後從第k 1個數開始,以k k i i 1,2,3.的概率選擇這個數,然後在蓄水池中隨機選擇乙個數,並將其替換,n個元素遍歷完畢後,蓄水池中的k個數就是隨機選擇的。證明 這裡即需要證明每個數出現...

蓄水池抽樣

給定乙個長度很長的資料流,在處理完成之前不知道其具體長度,如何在遍歷一遍資料流的情況下,隨機地抽出m個不重複的資料。key words 長度很長,遍歷完之前不可知 o n 複雜度 等概率地抽出m個數,每個數被抽中的概率為m n。如果接收的資料量小於m,直接放入蓄水池reservoir如果接收的數量大...