2012-03-31 31 views
2

我無法找到有關discrete_distribution的Boost版本的很多文檔。經過大量的Google搜索之後,我仍然無法找到這個類所具有的方法列表,以及它們中的任何一個函數是否可以重新分配概率。是boost :: random :: discrete_distribution是否可動態調整大小?

就我而言,我正在寫一個演化動力學算法。在每個時間步驟中,人口的成員可以隨機選擇死亡或複製。因此,離散分佈內的條目總數幾乎每次都會改變。

我想在模擬開始之前定義一個單獨的對象,稱爲gillespie_dist(管理此Gillespie算法的離散分佈)。但是我希望在每次迭代結束時可能會更改特定值和/或向gillespie_dist添加新值,並且不希望每次迭代都創建discrete_distribution的新實例。

這是一個很好的方法。有沒有將新值推送到對象上的方法,用於在特定索引處更改分佈值的方法,或者更好的方法是使用向量迭代器想法here以某種方式「重新初始化」整個分佈?

+0

'std :: discrete_distribution'可以完全用['param'](http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution/param)成員函數重新初始化,但是幾乎不會比創建新的'discrete_distribution'更便宜。我不認爲這些類是爲了有效地支持小型更新。 – leftaroundabout 2012-03-31 01:26:05

+0

正如前面的評論所暗示的,std :: discrete_distribution是去年的C++的一個標準功能:http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution – 2012-03-31 01:49:01

+0

注意到,但正如我的評論對於下面的答案,我認爲這是一個版本問題。當我嘗試使用'std :: discrete_distribution'時,我得到'error:'discrete_distribution'不是'std'的成員。我會很快更新,然後事情會更順利。 – ely 2012-03-31 01:52:31

回答

1

我看着GCC的代碼的libstdC++ 4.7實現的std :: discrete_distribution的。

權重在私人成員中存儲爲vector<double>。在公共界面中無法訪問其調整大小的方法。

我會嘗試挖掘其操作符()的實現(它看起來像cpp),它應該沒有問題推出自己的。

這裏是主要動作和我的解釋如下:

template<typename _IntType> 
    void 
    discrete_distribution<_IntType>::param_type:: 
    _M_initialize() 
    { 
     if (_M_prob.size() < 2) 
     { 
      _M_prob.clear(); 
      return; 
     } 

     const double __sum = std::accumulate(_M_prob.begin(), 
              _M_prob.end(), 0.0); 
     // Now normalize the probabilites. 
     __detail::__transform(_M_prob.begin(), _M_prob.end(), _M_prob.begin(), 
          std::bind2nd(std::divides<double>(), __sum)); 
     // Accumulate partial sums. 
     _M_cp.reserve(_M_prob.size()); 
     std::partial_sum(_M_prob.begin(), _M_prob.end(), 
         std::back_inserter(_M_cp)); 
     // Make sure the last cumulative probability is one. 
     _M_cp[_M_cp.size() - 1] = 1.0; 
    } 

    template<typename _IntType> 
    template<typename _UniformRandomNumberGenerator> 
     typename discrete_distribution<_IntType>::result_type 
     discrete_distribution<_IntType>:: 
     operator()(_UniformRandomNumberGenerator& __urng, 
       const param_type& __param) 
     { 
     if (__param._M_cp.empty()) 
      return result_type(0); 

     __detail::_Adaptor<_UniformRandomNumberGenerator, double> 
      __aurng(__urng); 

     const double __p = __aurng(); 
     auto __pos = std::lower_bound(__param._M_cp.begin(), 
             __param._M_cp.end(), __p); 

     return __pos - __param._M_cp.begin(); 
     } 

所以基本上它計算在初始化時的輔助的載體_M_cp基本上是權重的discete 累積性密度函數。因此,生成一個樣本就意味着生成一個統一的隨機變量並搜索累積分佈中的第一個事件(這是上面調用的lower_bound),返回它的索引。

例如,如果權重向量是:

{ 1, 2, 1, 3 } 

則CP的計算公式爲:

{ 1, 1+2, 1+2+1, 1+2+1+3 } 
= 
{ 1, 3, 4, 7 } 

所以均勻地選擇從0..6並且得到4,所以我挑第三個。

0

After much Google searching, I still can't even find a list of methods that this class has, and whether any of them function to re-assign the probabilities.

http://www.boost.org/doc/html/boost/random/discrete_distribution.html

void param(const param_type & param); 

Sets the parameters of the distribution.

+0

我明白了。問題在於我的系統具有Boost 1.42,並且看起來這個東西在該版本中並不存在於Boost :: random中。我將升級到當前的Boost版本,然後您指出的文檔將應用並應解決問題。一旦我得到這個工作,我一定會接受答案。謝謝。 – ely 2012-03-31 01:37:08

+0

我無法使這種方法工作。是否存在有關「param」類型的有效文檔?我已經嘗試過'std :: vector '這看起來是正確的例子,但它給出的錯誤是它無法找到該類型作爲參數的'param()'方法。 – ely 2012-03-31 04:06:48

+0

它實際上需要一個可以用各種方式初始化的param_type,但矢量不是其中之一。初始化爲{1.0,2.0,1.3}的數組可以工作,但這不是很靈活。還有可能適合你的迭代器,迭代器形式。 – DRVic 2012-03-31 12:07:06

相關問題