程式設計珠璣之取樣問題

2021-07-09 11:54:48 字數 1327 閱讀 1807

要從0~n-1的整數中取出來m(m第二種演算法和以前一篇的洗盤演算法比較相似,但是並不是嚴格的每個數字取到的概率為m/n,演算法是這樣的,先生成乙個n維的整數陣列,a值為0~n-1,然後生成m個n內的隨機整數rand,然後交換a[i]和a[rand](i=0...m-1)。至於是否是滿足m/n證明好像有點難。

第三種演算法更加直接,用乙個set容器存放產生的隨機整數,一直產生n內的隨機整數填入容器,一直到set的size為m的時候即可。

對於三種演算法,如果要求產生的整數為有序的,那麼第二第三中演算法還有排序,第一種演算法是自然有序的,但是當n較大的時候,第一種演算法執行的時間可能比較長。對於第一種演算法,當n較大,m較小的時候,可以判斷下m是否為0,如果為零可以跳出迴圈。還有別的情況,如果n和m都很大,而且m很接近n的時候,那麼可以產生n-m個n內的隨機整數,然後輸出沒有產生的隨機整數。還有當n為2的32次方,m為1000萬的時候,這種情況,可以直接生成1100萬個隨機的整數,然後去除重複的整數得到1000w個隨機整數。注意rand_max可能小於2的32次方,這時候就要對rand()函式進行改寫,假設rand_max為2的31次方,那麼可以寫個bigrand();

[cpp]view plain

copy

#include 

#include 

using

namespace

std;  

//rand()函式生成乙個0到rand_max(stdlib.h中定義的值為2147483647(有符號整數的最大值))之間的整數

void

rand_select1(

intn, 

intm);

//在0~n內選擇出m個整數

void

rand_select2(

intn, 

intm);  

void

rand_select3(

intn, 

intm);  

void

exchange(

int*a, 

inti, 

intj);  

intmain()  

void

rand_select1(

intn, 

intm)  

}  }  void

rand_select2(

intn, 

intm)  

void

rand_select3(

intn, 

intm)  

void

exchange(

int*a, 

inti, 

intj)  

程式設計珠璣 取樣問題

1.問題描述 程式的輸入包含兩個整數m和n,其中m2.解決思路與 實現 程式設計珠璣上給出了四個函式 1 genknuth 演算法依次考慮整數0,1,2,n 1,並通過乙個適當的隨機測試對每個整數進行選擇。通過按序訪問整數,可以保證輸出結果是有序的 c 實現 void genknuth int m,...

程式設計珠璣 取樣總結

問題描述 程式的輸入包含兩個整數m和n,其中m小於n。輸出是0 n 1範圍內的m個隨機整數,要求 每個數選擇出現的概率相等,且按序輸出。問題中最重要的要求是概率相同。假設m 2,n 5,那麼每個數都應該以2 5的概率被選中,直觀的會想到用這樣的 實現 if rand 5 2 然而這樣做是不對的,程式...

程式設計珠璣筆記 第12章 取樣問題

整理了這一章提到的幾個演算法,其中蓄水池演算法書中沒有寫,這裡放在一起比較一下,出了方法2是c 的 其它都是python的實現。問題 程式的輸入包括兩個整數m和n,其中m 1 以特定概率順序選擇每乙個數 如果要從r個剩餘的整數中選出s個,則以s r的概率選擇剩餘整數中的第乙個整數,然後遞迴處理剩下的...