2014-02-10 52 views
2

我想每次從分佈中抽樣時更改離散分佈的權重,而不必在每次繪製新的隨機樣本時初始化對象。Boost :: random :: discrete_distribution如何改變一次構建的權重

更改權重的原因是這是我正在實施的粒子濾波算法的一部分。我不想每次都實例化一個新對象的原因是我想以可控的方式將外部的隨機種子設置在整個程序的外部,以獲得可重複的結果。

相似的查詢,要求在這裏,但不太回答我的具體問題:

Boost random::discrete_distribution How to change weights once constructed? - 建議初始化每個畫

Why is boost's random number generation (on a normal distribution) always giving the same values? - 不改變參數

的問題是目前每次在一個更高級別的程序中,我調用包含隨機數生成的函數,我得到相同的隨機數序列。數字應該不同。

這是我正在嘗試做的簡化示例。

typedef boost::mt19937 RNGType; 
RNGType rng; 
nParticles = 10; 

int main() 
{  
    std::vector<int> indices(nParticles); 
    int nIterations(5); 
    for (int i=0; i<nIterations; ++i) 
    { 
    // Pseudo code. In the final version the weights will change on each loop 
    std::vector<double> weights = { 0.1, 0.4, ..., 0.3 }; // Vector length 10 
    indices = filter(weights); 
    std::cout << indices << std::endl; 
    } 
    return 0; 
} 

std::vector filter(std::vector<double> weights) 
{ 
    std::vector<int> indices(nParticles); 
    boost::random::discrete_distribution<int,double> weightdist(weights); 
    boost::variate_generator< RNGType, 
     boost::random::discrete_distribution<int,double> > 
     weightsampler(rng, weightdist); 
    for (int i=0; i<nParticles ; ++i) 
    { 
    indices[i] = weightsampler(); 
    } 
    return indices; 
} 

這返回,例如,

1,8,9,2,3,5,1,9,9,9 // Good: each number is "random" 
1,8,9,2,3,5,1,9,9,9 // Bad: This is the same as the previous line 
1,8,9,2,3,5,1,9,9,9 
1,8,9,2,3,5,1,9,9,9 
1,8,9,2,3,5,1,9,9,9 

有關如何爲每個過濾器函數輸出獲取不同數字的任何想法?

回答

1

您每次都在更改權重,因爲您在每次調用中都會將一組新權重傳遞給filter()函數。你的例子爲每次調用產生相同的輸出的原因是因爲boost::variate_generator's構造函數按值接受兩個參數。因此,您最終會在每次調用時製作RNG副本,並且原始RNG對象從不會看到副本內部狀態的更改。

變化的變量生成的模板參數爲引用類型

boost::variate_generator<RNGType&, boost::random::discrete_distribution<int,double>> 
//        ^^^ 
//    doesn't copy RNG anymore 

您可能還需要您filter()函數簽名改爲

std::vector filter(std::vector<double> const& weights) 

這將避免在每個輸入參數的不必要的複製呼叫。

Live demo

+0

優秀的解釋 – sehe

相關問題