1. 程式人生 > >隨機選取演算法 (有權重的記錄中選取)

隨機選取演算法 (有權重的記錄中選取)

三類隨機問題

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

    B5

    C1

首先,將第n行的數值賦為第n行加第n-1行的,遞迴執行,如下:

    A10

    B15

    C16

然後每次從[1,16]隨機選取一個數,如果落在[1,10]之間,則選取A,如果落在(10,15]之間則選B,如果落在(16,16]之間則選取C, 圖示如下,誰佔的區間大(權重高),被選上的概率更大。


 知道了思路,實現起來就比較方便了, 需要考慮的一點可能就是我隨即選了一個數值,比如12,我怎麼跟B對應上? 其實也比較簡單,用二分法查詢即可。

下面附上實現程式碼:

#include <string>
#include <cstdlib>
#include <vector>

using namespace std;

const int LEN = 4098; 
const int MAX_QUERY_LEN = 2048;

//返回屬於[p,q)的隨機數
int rand(int p, int q)
{
     int size = q-p+1;
     return  p+ rand()%size; 
}

//刪除行尾換行符
int chomp(char *str)
{
    int len = strlen(str);
    while(len > 0 && (str[len - 1] == '\n' || str[len - 1] == '\r'))
    {
        str[len - 1] = 0;
        len--;
    }
    return len;
}

//獲取一個隨機數會落在哪個區間
int get_pos(vector<int> vec_freq, int begin, int end, int rand_num)
{
    if(begin >= end)
    {
        return begin;
    }
    
    int mid = (begin + end)/2;
    if( vec_freq[mid] >= rand_num )
    {
        return get_pos(vec_freq, begin, mid, rand_num );
    }
    else
    {
        return get_pos(vec_freq, mid+1, end, rand_num );
    }
}

//主函式
int main(int argc, char *argv[])
{
    //輸入記錄檔案,兩列,第一列為記錄,第二列為熱度值
	FILE* infile = fopen(argv[1], "r");
	if( infile == NULL )
	{
		printf("Cann't open file %s.", argv[1]);
		return -1;
	}

	FILE* outfile = fopen(argv[2], "w");
	if( outfile == NULL)
	{
		printf("Cann't open file %s to write.", argv[2]);
		return -1;
	}

    //要獲取的隨機記錄個數
    int num = atoi(argv[3]);
    if( num <= 0)
    {
        printf("num [%s] <= 0.");
        return -1;
    }

    //這兩個陣列用下標關聯
    vector<string> vec_query;
    vector<int> vec_freq;
    vec_query.clear();
    vec_freq.clear();
    int freq = 0;
    char line[MAX_QUERY_LEN]={0};
    
		while( !feof(infile) )
		{
			if( !fgets(line, sizeof(line),infile))
			{
				break;
			}
        line[sizeof(line)-1] = 0;
		    chomp(line);

        char* p_tab = strchr(line, '\t');
        if( NULL == p_tab )
        {
            printf("line format error. [%s]\n");
            continue;
        }
        *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)
    {
        int rand_num = rand(1, freq+1);
        int pos = get_pos(vec_freq, 0, vec_freq.size(), rand_num);
        fprintf(outfile, "%s\t%d\t%d\n", vec_query[pos].c_str(), vec_freq[pos], rand_num);
    }
    
	fclose(infile);
	fclose(outfile);	

	return 0;
}


相關推薦

隨機選取演算法 (權重記錄選取)

三類隨機問題 1.  已有n條記錄,從中選取m條記錄,選取出來的記錄前後順序不管。      實現思路:按行遍歷所有記錄,約隔n/m條取一個數據即可 2.  在1類情況下,還要求選取出來的m條記錄是隨機排序的      實現思路: 給n條記錄,分別增加一列標記,值為隨機

計算機視覺:隨機森林演算法在人體識別的應用

摘 要 人體識別是計算機視覺領域的一大類熱點問題,其研究內容涵蓋了人體的監測與跟蹤、手勢識別、動作識別、人臉識別、性別識別和行為與事件識別等,有著非常廣泛的應用價值。隨機森林以它自身固有的特點和優良的分類效果在眾多的機器學習演算法中脫穎而出。隨機森林演算法的實質是一

演算法:在一個集合選取所有符合條件的元素組合

做了好幾個題目都遇到題中的場景。於是寫了個演算法,元素組合條件是求和。 演算法能適應的場景要求組合條件可以拆分的,有對應的逆運算。 程式碼實現的是取三個元素和在40~60之間的組合。迴圈n(testList.size())次可以獲取所有符合條件的組合。

oracle 查詢列表選取其中一行

lec where num 中一 rac sel esc emp 一行 select k.SAL from (select SAL,rownum rn from (select SAL from SCOTT.EMP where MGR = 7698 order by

相簿選取圖片插入到EditText,實現圖文混排

1.首先用到了 ImagePicker,上github搜尋仿微信圖片選擇就能找到 2.匯入ImagePicker的包 compile 'com.squareup.picasso:picasso:2.5.2' 3.我是用是 picasso載入圖片,github上imag

織夢選取特定的文章

注意:選取指定的文章,只能在arclist標籤裡,list是不能選取的,同時也沒有typeid 第一種指定文章的id來呼叫特定文件:: {dede:arclist row=1 idlist='6'} <li><a href="[field:arcurl/]">[

前端之路:sql語句,表隨機獲取一條記錄(資料)。(或者獲取隨機獲取多條(記錄)資料)

<!--表中獲取隨機一條title 耗時0.01s id==隨機欄位,最好為表id--> SELECT * FROM `tableName` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `ta

Leetcode---陣列的第K個最大元素--隨機演算法

陣列中的第K個最大元素 題目連結:陣列中的第K個最大元素 思路: 如果先排序,不管利用哪個,比較排序時間複雜度最優為O(nlgn) 但是我們發現,快排的一趟排列有一定的性質,我們可以求得一趟快排之後,該數在整個陣列中排在第幾位,且將整個陣列劃分為兩段 利用這個

pandas.DataFrame選取、修改資料.loc,.iloc,.ix

本文轉載自:https://blog.csdn.net/hecongqing/article/details/61927615 loc——通過行標籤索引行資料 iloc——通過行號索引行資料 ix——通過行標籤或者行號索引行資料(基於loc和iloc 的混合) 同

C 試基於圖的深度優先搜尋策略寫一演算法 判別以鄰接表方式儲存的向圖是否存在由頂點 vi到頂點 vj的路徑 i≠j 。

嚴蔚敏 資料結構 7.22 給大佬跪了,這個是要返回的,但是還要兼顧頂點上連線的其他節點,不能一個不行就不行,所以走的路徑只返回走通的,走不通的略過,直到最後,能走到最後就說明根本沒有通的路徑,就這樣。 也可以把這個點上的所有連線點用深度遍歷走一次,然後看看記錄

data_structure_and_algorithm -- 雜湊演算法(下):雜湊演算法在分散式系統哪些應用?

今天主要看一下雜湊演算法的應用(二),主要參考:前谷歌工程師王爭的課程,感興趣可以通過下面方式微信掃碼購買: 你可能已經發現,這三個應用都跟分散式系統有關。沒錯,今天我就帶你看下,雜湊演算法是如何解決這些分散式問題的。 應用五:負載均衡 我們知道,負載均衡演算法

jquery選取兄弟節點的方法

$('#id').siblings() 當前元素所有的兄弟節點$('#id').prev() 當前元素前一個兄弟節點$('#id').prevaAll() 當前元素之前所有的兄弟節點$('#id').next() 當前元素之後第一個兄弟節點$('#id').nextAll(

Android從相簿選取圖片上傳到阿里雲OSS

    在開發APP軟體中,boss突然提出想在軟體中新增一個多張照片上傳的功能,作為菜鳥的我,琢磨了兩天,才弄出來,今天特地貼出來。本篇部落格主要介紹的是將本地圖片上傳到伺服器的方法技巧。主要技術點是: 一、運用第三方可以從相簿中選取多張圖片。 二、將圖片

整合學習boosting、bagging、隨機森林演算法的介紹

整合學習的概念 定義:整合學習通過構建並結合多個學習器來完成學習任務。 分類:只包含同種型別的個體學習器,這樣的整合是“同質”的,例如都是神經網路或者決策樹;包含不同型別的個體學習器,這樣的整合是“異質”的,例如同時包括神經網路和決策樹。 作用:整合學習通過將多個學習器

從整合方法到神經網路:自動駕駛技術的機器學習演算法哪些?

來源:機器之心 編譯:Lj Linjing、蔣思源 物聯網智庫 原創 轉載請註明來源和出處 ------   【導讀】------ 機器學習演算法可以融合來自車體內外不同感測器的資料,從而評估駕駛員狀況或者對駕駛場景進行分類。本文將粗略講解一下各類用於自動駕駛技術的演算法。 如今,機器

從n個數選取m個數的所有組合

非遞迴實現: #define N 7 #define M 3 int main() { int array[N] = { 1,2,3,4,5,6 ,7 }; int i, j, k; for (i = 0; i<=N-M; i++) for (j = i +

Matlab從影象選取矩形區域

imrect a = imread(‘lena8.jpg’); b = imcrop(); % 得到矩形區域的畫素矩陣 imcrop a = imread(‘lena8.jpg’); b = imrect; h = wait(b);%得到矩形的起

數字影象處理常用影象分割演算法哪些?

數字影象處理中常用影象分割演算法有哪些? 1.多數的影象分割演算法 2.影象邊緣分割 3.影象閾值分割 4.基於區域的分割 5.形態學分水嶺演算法 多數的影象分割演算法 均是基於灰度值的不連續和相似的性質。在前者中,演算法以灰度突變為基礎分割一幅影象,如影象邊緣分割

mysql 重複記錄選取最後一條

// sid相同,create_time不同,取create_time最後一條 1. 使用 NOT EXISTS引數 SELECT id, sid FROM table_name a WHERE NOT EXISTS (SELECT 1 FROM table_name w

Android開發從相簿選取照片

最近專案在做一個功能:就是需要從使用者選擇頭像跳轉到相簿選擇圖片,這應該是一個很簡單的需求,但是在網上搜了一下有好多都講的很亂,其實用幾十行程式碼就可以實現的為什麼要說的那麼複雜呢,下面就簡單說一下嘍。 下面說兩種方法分別是直接選擇相簿返回,另外一種為選擇相簿之