2

ブーストバージョンのdiscrete_distributionのドキュメントがあまり見つかりません。多くのグーグル検索の後、私はまだこのクラスが持っているメソッドのリスト、そしてそれらのどれかが確率を再割り当てするために機能するかどうかさえ見つけることができません。

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

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

このための良いアプローチは何ですか。オブジェクトに新しい値をプッシュする方法、特定のインデックスで分布の値を変更する方法、さらに良いことに、ここでdiscrete_distribution説明したベクトルイテレータのアイデアを使用して分布全体を何らかの方法で「再初期化」する方法はありますか?

4

2 に答える 2

1

std::discrete_distributionのgcclibstdc++4.7実装のコードを調べました。

重みはvector<double>プライベートメンバーにとして保存されます。パブリックインターフェイスでは、そのサイズ変更メソッドにアクセスできません。

私はそのoperator()の実装を掘り下げてみます(これは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したがって、基本的には、初期化時に補助ベクトルを計算します。これは、本質的に重みの離散累積密度関数です。したがって、サンプルを生成するということは、一様確率変数を生成し、それが累積分布で最初に出現するものを検索して(これは上記のlower_bound呼び出しです)、そのインデックスを返すことを意味します。

たとえば、重みベクトルが次の場合:

{ 1, 2, 1, 3 }

次に、cpは次のように計算されます。

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

だから私は0..6から一律に選択して4を取得するので、3番目のものを選びます。

于 2012-03-31T01:58:19.990 に答える
0

多くのグーグル検索の後、私はまだこのクラスが持っているメソッドのリスト、そしてそれらのどれかが確率を再割り当てするために機能するかどうかさえ見つけることができません。

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

void param(const param_type & param);

分布のパラメーターを設定します。

于 2012-03-31T01:26:09.653 に答える