Boost :: random :: discrete_distribution如何在构造后更改权重

时间:2014-02-10 15:59:21

标签: c++ boost random random-sample

每次从分布中采样时,我都想更改离散分布的权重,而不必在每次绘制新的随机样本时初始化对象。

改变权重的原因是这是我正在实现的粒子滤波算法的一部分。我不希望每次实例化一个新对象的原因是我想以受控方式在外部将随机种子设置为整个程序,以获得可重复的结果。

这里会询问类似的问题,但不能完全回答我的具体问题:

Boost random::discrete_distribution How to change weights once constructed? - 建议在每次抽奖时进行初始化

Why is boost's random number generation (on a normal distribution) always giving the same values? - 不会更改参数

问题是目前每次在一个更高级别的程序中我调用包含随机数生成的函数,我得到相同的随机数序列。数字应该不同。

这是我想要做的简化示例。

typedef boost::mt19937 RNGType;
RNGType rng;
nParticles = 10;

int main()
{      
  std::vector<int> indices(nParticles);
  int nIterations(5);
  for (int i=0; i<nIterations; ++i)
  {
    // Pseudo code. In the final version the weights will change on each loop
    std::vector<double> weights = { 0.1, 0.4, ..., 0.3 }; // Vector length 10
    indices = filter(weights);
    std::cout << indices << std::endl;
  }
  return 0;
}

std::vector filter(std::vector<double> weights)
{
  std::vector<int> indices(nParticles);
  boost::random::discrete_distribution<int,double> weightdist(weights);
  boost::variate_generator< RNGType, 
      boost::random::discrete_distribution<int,double> >
      weightsampler(rng, weightdist);
  for (int i=0; i<nParticles ; ++i)
  {
    indices[i] = weightsampler();
  }
  return indices;
}

返回,例如

1,8,9,2,3,5,1,9,9,9 // Good: each number is "random"
1,8,9,2,3,5,1,9,9,9 // Bad: This is the same as the previous line
1,8,9,2,3,5,1,9,9,9
1,8,9,2,3,5,1,9,9,9
1,8,9,2,3,5,1,9,9,9

有关如何为每个过滤器函数输出获取不同数字的任何想法?

1 个答案:

答案 0 :(得分:1)

您每次都在更改权重,因为您在每次调用时都会向filter()函数传递一组新权重。您的示例为每个调用生成相同输出的原因是因为boost::variate_generator's构造函数按值获取两个参数。因此,您最终会在每次调用时复制RNG,并且原始RNG对象永远不会看到对副本内部状态的更改。

将variate生成器的模板参数更改为引用类型

boost::variate_generator<RNGType&, boost::random::discrete_distribution<int,double>>
//                             ^^^
//               doesn't copy RNG anymore

您可能还想将filter()功能签名更改为

std::vector filter(std::vector<double> const& weights)

这样可以避免在每次调用时不必要地复制输入参数。

Live demo