2012-03-31 17 views
2

私はdiscrete_distributionのBoostバージョンの多くのドキュメントを見つけることができません。多くのGoogle検索の後で、私はまだこのクラスが持っているメソッドのリストとそれらのどれかが確率を再割り当てする機能を持っているかどうか見つけることさえできません。boost :: random :: discrete_distributionは動的にサイズ変更できますか?

私の場合、私は進化的ダイナミクスアルゴリズムを書いています。各時間ステップで、集団のメンバーを無作為に選択して死亡または再現することができます。このため、離散分布内のエントリーの総数はほぼすべての反復で変更されます。

gillespie_dist(このGillespieアルゴリズムを支配する離散分布)と呼ばれる、シミュレーションが開始される前に私が定義した単一のオブジェクトが必要です。しかし、各反復の終わりに、特定の値を変更したり、新しい値をgillespie_distに追加したり、繰り返しごとにdiscrete_distributionの新しいインスタンスを作成することは特に望ましくありません。

これにはどのような方法が適していますか? discrete_distributionオブジェクトに新しい値をプッシュするメソッド、特定のインデックスでディストリビューションの値を変更するメソッド、またはより良い方法として、hereというベクトルイテレータのアイデアを使用して、ディストリビューション全体を何らかの形で再初期化する方法がありますか?

+0

'std :: discrete_distribution'は[' param'](http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution/param)メンバ関数で完全に再初期化できますが、新しい 'discrete_distribution'を作成するよりも安価にすることはほとんどありません。私はこれらのクラスが小規模な更新を効率的にサポートするものではないと思います。 – leftaroundabout

+0

前のコメントで暗示されているように、std :: discrete_distributionは昨年現在のC++の標準機能です。http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution –

+0

注目されていますが、コメントにあります以下の答えに、私はこれがバージョンの問題だと思う。 'error: 'discrete_distribution'を使用しようとすると、 'discrete_distribution'は 'std'のメンバーではありません。私はまもなく更新され、物事はよりスムーズになるはずです。 – ely

答えて

1

私はSTDのGCCのlibstdC++ 4.7の実装:: discrete_distributionのコードに見えました。

重みは、vector<double>としてプライベートメンバーに格納されます。パブリックインターフェイスのresizeメソッドへのアクセスはありません。

私はそのオペレータ()(これは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(); 
     } 

だから、基本的には、本質的に重みのdiscete cummulative密度関数で初期化時にauxilaryベクトル_M_cpを計算します。したがって、標本を生成することは、均一な確率変数を生成し、カミック分布における最初の出現を検索することを意味します(これは上ののlower_bound です)、そのインデックスを返します。

例えば、重みベクトルがある場合:その後、CPは次のよ​​うに計算され

{ 1, 2, 1, 3 } 

{ 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

+0

このメソッドを動作させることができません。 'param'型のために有効であるものとして受け入れられているものに関する文書はありますか?私は 'std :: vector 'を試してみましたが、これは例のようですが、引数としてその型を持つ 'param()'メソッドを見つけることができないというエラーを出します。 – ely

+0

実際にはさまざまな方法で初期化できるparam_typeが必要ですが、ベクトルはその1つではありません。 {1.0,2.0,1.3}のように初期化された配列は動作しますが、あまり柔軟性がありません。また、イテレーター、イテレーターのフォームがあなたのために働くかもしれません。 – DRVic

関連する問題