三類隨機問題
1. 已有n條記錄,從中選取m條記錄,選取出來的記錄前後順序不管。
實現思路:按行遍歷所有記錄,約隔n/m條取乙個資料即可
2. 在1類情況下,還要求選取出來的m條記錄是隨機排序的
實現思路: 給n條記錄,分別增加一列標記,值為隨機選取的1至n之間的不重複資料,
實現參考博文將檔案內容按行隨機排列
3. 區別於1,2類問題, 如果記錄是有權重的,如何結合權重去隨機選取。 比如a的權重為10, b的權重股為5, c的權重為1, 則隨機選取4個時可能應該出現aabb。
這第三類問題是本文重點,下面開始解決。
實現思路:以 a:10, b:5, c:1 三條記錄上隨機選取4條為例,(是否以權重排序這個無所謂)
對於a10
b5c1
首先,將第n行的數值賦為第n行加第n-1行的,遞迴執行,如下:
a10b15
c16然後每次從[1,16]隨機選取乙個數,如果落在[1,10]之間,則選取a,如果落在(10,15]之間則選b,如果落在(16,16]之間則選取c, 圖示如下,誰佔的區間大(權重高),被選上的概率更大。
知道了思路,實現起來就比較方便了, 需要考慮的一點可能就是我隨即選了乙個數值,比如12,我怎麼跟b對應上? 其實也比較簡單,用二分法查詢即可。
下面附上實現**:
#include #include #include using namespace std;
const int len = 4098;
const int max_query_len = 2048;
//返回屬於[p,q)的隨機數
int rand(int p, int q)
//刪除行尾換行符
int chomp(char *str)
return len;
}//獲取乙個隨機數會落在哪個區間
int get_pos(vectorvec_freq, int begin, int end, int rand_num)
int mid = (begin + end)/2;
if( vec_freq[mid] >= rand_num )
else
}//主函式
int main(int argc, char *argv)
file* outfile = fopen(argv[2], "w");
if( outfile == null)
//要獲取的隨機記錄個數
int num = atoi(argv[3]);
if( num <= 0)
//這兩個陣列用下標關聯
vectorvec_query;
vectorvec_freq;
vec_query.clear();
vec_freq.clear();
int freq = 0;
char line[max_query_len]=;
while( !feof(infile) )
line[sizeof(line)-1] = 0;
chomp(line);
char* p_tab = strchr(line, '\t');
if( null == p_tab )
*p_tab = 0;
string query(line);
freq += atoi(p_tab+1);
vec_query.push_back(query);
vec_freq.push_back(freq);
//printf("%s\t%d\n", line, freq);
} for(int i=0; i < num; ++i)
fclose(infile);
fclose(outfile);
return 0;
}
隨機選取演算法 有權重的記錄中選取
三類隨機問題 1.已有n條記錄,從中選取m條記錄,選取出來的記錄前後順序不管。實現思路 按行遍歷所有記錄,約隔n m條取乙個資料即可 2.在1類情況下,還要求選取出來的m條記錄是隨機排序的 實現思路 給n條記錄,分別增加一列標記,值為隨機選取的1至n之間的不重複資料,實現參考博文將檔案內容按行隨機排...
織夢中選取特定的文章
注意 選取指定的文章,只能在arclist標籤裡,list是不能選取的,同時也沒有typeid field description 例子 所有只需在arclist裡加入idlist 373,387,277 表示呼叫id號為373,387,277的文件。field title 第二種 指定keywor...
按權重選取目標的java演算法
最近在做乙個武將系統,是乙個比較繁瑣的系統,用例比較多。安排了兩周時間給我開發,但是光是開發的話一周就夠了,剩下的時間用來除錯。關於這個系統,個人比較感興趣的是其中與權重有關的部分。每個武將有不同的出現機率,且每個武將對應多個權重不同的成長值。這裡有兩處地方與權重有關了,剛開始以為自己寫了個很巧妙的...