2011-03-14 21 views
8

我用下面的代碼來創建整數與一範圍內均勻分佈。 (我拿出播種代碼)眼下創建非均勻,整分配使用TR1 <random>

int random(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::uniform_int<int> dist(min, max); 
    return dist(gen); 

} 

我想修改它給予有利於twords最小值分佈,幾乎從不接近最大值。我可以看到所有預先製作的發行版,但沒有一個是整數。而且我也無法根據任何文檔分辨哪一個符合我的需求。我來最接近的是卡方分佈如圖所示在維基百科上,其中k = 2

但我想不通的基礎上,documentation如何與整數使用它,更不用說集合k值。

我如何設置我的功能,使用適當的不均勻,整數分佈?


仍然工作在選擇正確的發行版:這裏是std::poisson_distribution<int> dist((max - min) * .1);從0至20的結果:

還沒有應用,爲0應該比1更加頻繁,但它應該幫助下一個人出來後會發佈更多的結果。


以及我的最終解決方案成爲相結合的方法:

int randomDist(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::chi_squared_distribution<double> dist(2); 

    int x; 
    do 
    { 
    x = (int)(max*dist(gen)/10) + min; 
    } 
    while (x > max); 
    return x; 
} 

給出的結果是:

+0

在泊松分佈中,如果選擇小於1的參數(當前(20-0)*。1 = 2),則0會比1更頻繁。您還可以通過任何參數進行幾何分佈。您應該選擇哪一個取決於您正在建模的內容:幾何模型直到事件發生的時間(例如,評分目標所需的投籃次數),泊松模型在一段時間內(例如,數字遊戲中的目標)。 – aaz 2011-03-14 12:33:51

+1

那麼我用它來實時遺傳算法。與其有獨特的一代,當我們開始培育一種新的有機體時,我通過健身來挑選它們,並根據這條曲線選擇父母。 – Zak 2011-03-14 21:54:22

+0

@Zak - 如果選擇使用幾何分佈,則可以將每個父母的選擇描述爲#1 vs(#2 vs(獲勝者#3 vs ...))的比賽),其中#i獲勝對任何#j,我 aaz 2011-03-14 22:41:04

回答

9

還有其他的整數分佈在那裏,他們只是不在他們的名字中有int。他們有他們的類定義typedef IntType result_type

其表現爲你描述的是:

  • binomial_distribution(t, p)

    此範圍內生成數字0≤X,所以你需要通過翻譯的範圍min。均值是在噸·P,因此選擇一個p接近0

    std::binomial_distribution<int> dist(max - min, .1);
    return dist(gen) + min;

  • poisson_distribution(λ)

    這產生數字0≤X <∞,但大量逐漸減少。您可以審查超出max的任何內容以將其限制在一定範圍內。參數λ是平均值。選擇它前面的例子匹配:

    std::poisson_distribution<int> dist((max - min) * .1);
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

  • geometric_distribution(p)

    還生成數字0≤X <∞,但0是最有可能的結果,並且每個後續數字都比以前少。再次選擇參數匹配前面的例子的意思是:

    std::geometric_distribution<int> dist(1/((max - min) * .1 + 1));
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

您也可以使用任何連續分佈來生成一個double然後四捨五入它到int

6

除了分佈在說@aaz「偉大的回答,請記住,你也可以改變你的均勻分佈,以你可能想到的任何概率分佈函數,使用inverse transform sampling(即但是實際上是可行的只有對於一些「好」功能)或rejection sampling(可以在任何情況下應用,但是可能在計算上是昂貴的)。

在我看來,這將滿足您的需求分佈將是(負)exponential distribution

Exponential distribution

幸運的是,這是你可以申請反變換抽樣分佈之一,這意味着,從均勻具有樣品[0,1]的分佈,可以通過應用下面的公式得到一個指數分佈:

x = - ln(1-p)/lambda 

p是隨機VAL ue從均勻分佈和lambda是指數分佈的參數;有關更多信息,請參閱here

一旦你x(這將是一個double),只是它(與函數或圓形像:

int round(double val) 
{ 
    // warning: can give counterintuitive results with negative numbers 
    return int(val+0.5); 
} 

)轉換爲int獲得你的結果。


編輯

順便說一句,我沒有注意到,即使是指數分佈已經包含在<random>link)...好,甚至更好,你不需要編寫代碼,但一點理論從不浪費:)