2012-08-02 35 views
0

我必須運行一個模擬,其中每個事件E_i都有一定的概率P_i發生(i = 1..4,sum_i P_i = 1)。選擇具有不同概率的事件 - C++

我想寫一個函數,將四個不同的概率(它們取決於模擬中發生的其他事情)作爲輸入,返回所選事件的整數i。

這是編寫這樣一個函數的最好方法(可能只使用標準庫, 我必須在一個沒有擁有添加新庫的權限的集羣上運行它)?

我的想法寫類似:

int get_event(double p1,double p2, double p3, double p4){ 
    double r=((double) rand())/(RAND_MAX); // alternatively here there can be any function that 
    // generates a random number uniformly distribute in (0,1); 
    if (r<=p1) return 1; 
    else if (r>p1 && r <=(p1+p2)) return 2; 
    else if (r>(p1+p2) && r <=(p1+p2+p3)) return 3; 
    else if (r>(p1+p2+p3) && r <=1) return 4; 
    else return -1; // -1 is an en error code; 
} 

,但我不知道這是最好的辦法。任何建議? 非常感謝。

回答

3

這是相當不錯的,我建議只有一些小的改動:

int get_event(double p1,double p2, double p3, double p4){ 
    double r=((double) rand())/(RAND_MAX); 
    if (r<=p1) return 1; 
    r-= p1; 
    if (r<=p2) return 2; 
    r-= p2; 
    if (r<=p3) return 3; 
    r-= p3; 
    if (r<=p4) return 4; 
    return -1; // -1 is an en error code; 
} 
+0

感謝它似乎是一個非常優雅的解決方案! – lucacerone 2012-08-02 13:49:19

+0

[facepalm]謝謝,@LokiAstari。 – Beta 2012-08-02 14:04:28

+0

多次連續減法的累積誤差會成爲問題嗎? – Omaha 2012-08-02 14:48:44

2

下面是一個例子,而使其成爲較大概率的數工作,你如何概括你的代碼。此外,我已經包括了eps的比較。

const double eps = 1e-9; 
int get_event(double p[], int psize){ 
    double r=rand()/(RAND_MAX); // alternatively here there can be any function that 
    // generates a random number uniformly distribute in (0,1); 
    for (int i = 1; i <= psize; ++i) { 
     r -= p[i-1]; 
     if (r < eps) { 
     return i; 
     } 
    } 
    return -1; // -1 is an en error code; 
} 
+0

我喜歡這個概念,感謝您的建議! – lucacerone 2012-08-02 13:53:37

+0

只是一個小小的評論,rand返回一個int值,所以結果需要在被RAND_MAX除之前進行轉換。這對於迄今爲止發佈的所有實現都很常見! – lucacerone 2012-08-02 14:28:26

+0

@LucaCerone其實我的代碼是基於你的。我沒有修改生成隨機數本身的部分。 – 2012-08-02 14:30:21