C++ boost::random::discrete_分布是否可以动态调整大小?
我找不到很多关于离散分布的Boost版本的文档。在谷歌搜索了很多次之后,我仍然找不到这个类拥有的方法列表,也找不到是否有任何方法可以重新分配概率 在我的例子中,我正在写一个进化动力学算法。在每个时间步,可以随机选择种群成员死亡或繁殖。因此,我的离散分布中的条目总数几乎在每次迭代中都会发生变化 我希望在模拟开始之前定义一个对象,称为C++ boost::random::discrete_分布是否可以动态调整大小?,c++,boost,probability,boost-random,dynamic-resizing,C++,Boost,Probability,Boost Random,Dynamic Resizing,我找不到很多关于离散分布的Boost版本的文档。在谷歌搜索了很多次之后,我仍然找不到这个类拥有的方法列表,也找不到是否有任何方法可以重新分配概率 在我的例子中,我正在写一个进化动力学算法。在每个时间步,可以随机选择种群成员死亡或繁殖。因此,我的离散分布中的条目总数几乎在每次迭代中都会发生变化 我希望在模拟开始之前定义一个对象,称为gillespie_dist(控制此gillespie算法的离散分布)。但我希望在每次迭代结束时,潜在地更改特定值和/或向gillespie_dist添加新值,特别是不
gillespie_dist
(控制此gillespie算法的离散分布)。但我希望在每次迭代结束时,潜在地更改特定值和/或向gillespie_dist添加新值,特别是不希望在每次迭代中创建离散分布的新实例
这方面的好方法是什么。是否有方法将新值推送到离散分布
对象上,或者有方法在特定索引处更改分布的值,或者更好的是,使用上述向量迭代器思想以某种方式“重新初始化”整个分布
在谷歌搜索了很多次之后,我仍然找不到一个方法列表
该类具有,以及其中是否有函数用于重新分配
概率
及
设置分布的参数
我研究了std::discrete_发行版的gcc libstdc++4.7实现的代码 权重作为向量存储在私有成员中。无法在公共界面中访问其调整大小方法 我将尝试挖掘它的操作符()的实现(看起来像是在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();
}
然后计算cp,如下所示:
{ 1, 1+2, 1+2+1, 1+2+1+3 }
=
{ 1, 3, 4, 7 }
所以我从0..6中统一选择,得到4,所以我选择第三个。
std::discrete_distribution
可以使用成员函数完全重新初始化,但这几乎不会比创建新的discrete_distribution
便宜。我不认为这些类是为了有效地支持小更新。正如前一个评论所暗示的,STD::DisteTyPaySt配送是C++去年的标准特征:注意到,但是在我的评论中,下面的答案,我认为这是一个版本问题。当我尝试使用std::discrete\u distribution
时,我发现错误:“discrete\u distribution”不是“std”的成员。我很快就会更新,到时候事情会更顺利。@EMS:您使用的编译器和版本是什么?g++(Ubuntu/Linaro 4.4.5-15ubuntu1)4.4.5我知道了。问题是我的系统有Boost 1.42,而在那个版本中Boost::random中似乎不存在这种东西。我将升级到当前的Boost版本,然后您指向我的文档将适用,并且应该可以解决问题。一旦我成功了,我一定会接受答案。谢谢。我不能用这种方法。对于“param”类型,是否有文件证明什么是有效的?我尝试了std::vector
,这在示例中似乎是正确的,但它给出的错误是找不到以该类型为参数的param()
方法。它实际上需要一个可以以各种方式初始化的param_类型,但vector不是其中之一。一个初始化为{1.0,2.0,1.3}的数组可以工作,但这不是很灵活。还有迭代器,迭代器形式可能适合您。当我尝试将两个std::vector迭代器传递给它时,会遇到相同的错误。它说它找不到将这些类型作为输入的方法。问题是,我需要动态调整大小,因此必须形成一个有界内存数组,这会破坏我从使用此方法中获得的所有收益。我需要一些离散的分布对象,它可以接受动态调整大小的容器并更新其概率以匹配它们,无论这意味着增加或减少以前的分布大小。这看起来不是这样的,除非我刚开始做一些大规模的规则数组
{ 1, 2, 1, 3 }
{ 1, 1+2, 1+2+1, 1+2+1+3 }
=
{ 1, 3, 4, 7 }