【问题标题】:Boost::random::discrete_distribution How to change weights once constructedBoost::random::discrete_distribution 构造后如何更改权重
【发布时间】:2023-04-07 08:51:02
【问题描述】:

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

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

此处提出了类似的查询,但不能完全回答我的具体问题:

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

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

【问题讨论】:

    标签: c++ boost random random-sample


    【解决方案1】:

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

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

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      相关资源
      最近更新 更多