简体   繁体   English

boost :: random :: discrete_distribution是否可以动态调整大小?

[英]Is boost::random::discrete_distribution dynamically resizable?

I cannot find much documentation of the Boost version of discrete_distribution. 我找不到关于Boost_discrete_distribution的大量文档。 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. 在Google大量搜索之后,我什至找不到该类具有的方法列表,以及它们中的任何一个是否可以重新分配这些概率。

In my case, I am writing an evolutionary dynamics algorithm. 就我而言,我正在编写一种进化动力学算法。 At each time step, members of the population can be randomly selected to either die or reproduce. 在每个时间步长,可以随机选择种群成员去死或繁殖。 Because of this, the total number of entries within my discrete distribution will change almost every iteration. 因此,离散分布中的条目总数几乎每次迭代都会更改。

I want to have a single object that I define before the simulation starts, called gillespie_dist (the discrete distribution governing this Gillespie algorithm). 我想在仿真开始之前有一个定义的对象,称为gillespie_dist (控制此Gillespie算法的离散分布)。 But I want, at the end of each iteration, to potentially change specific values and/or add new values to gillespie_dist and specifically do not want to create new instances of the discrete_distribution every iteration. 但是我希望在每次迭代结束时潜在地更改特定值和/或向gillespie_dist添加新值,特别是不想在每次迭代中都创建离散实例的新实例。

What is a good approach for this. 有什么好的方法。 Are there methods for pushing a new value onto the discrete_distribution object, methods for changing a distribution's value at a particular index, or better yet, somehow "re-initializing" the entire distribution using the vector iterator idea mentioned here ? 是否有用于将新值推送到discrete_distribution对象上的方法,用于更改特定索引处的分布值的方法,或者更好的方法是使用此处提到的向量迭代器思想以某种方式“重新初始化”整个分布?

I looked into the code of the gcc libstdc++ 4.7 implementation of std::discrete_distribution. 我研究了std :: discrete_distribution的gcc libstdc ++ 4.7实现的代码。

The weights are stored as a vector<double> in a private member. 权重作为vector<double>存储在私有成员中。 There is no access to its resize method in the public interface. 在公共接口中无法访问其调整大小方法。

I'll try and dig out the implementation of its operator() (which is in the cpp it looks like), it should be no trouble to roll your own. 我将尝试找出其operator()的实现(看起来像在cpp中),滚动自己的应该没什么麻烦。

Here is the main action, and my explanation following: 这是主要动作,下面是我的解释:

  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();
      }

So basically it calculates an auxilary vector _M_cp at initialization time which is essentially a discete cummulative density function of the weights. 因此,基本上,它在初始化时计算_M_cp向量_M_cp ,该向量_M_cp是权重的离散累积密度函数。 So producing a sample just means generating a uniform random variable and searching for the first occurence of that in the cummulative distribution (this is the lower_bound call above), returning its index. 因此,生成样本仅意味着生成一个统一的随机变量,并在累积分布中搜索该变量的首次出现(这是上面的lower_bound调用),并返回其索引。

eg, if the weights vector is: 例如,如果权重向量为:

{ 1, 2, 1, 3 }

then the cp is calculated as: 那么cp的计算公式为:

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

so I uniformly select from 0..6 and get 4, so I pick the third one. 所以我统一选择0..6并得到4,所以我选择了第三个。

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. 在Google大量搜索之后,我什至找不到该类具有的方法列表,以及它们中的任何一个是否可以重新分配这些概率。

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

and

void param(const param_type & param);

Sets the parameters of the distribution. 设置分布的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM