如何在类中重用和重新初始化c ++ discrete_distribution?

时间:2017-08-24 02:56:43

标签: c++ random boost boost-random

我正在c ++类中编写一个离散分布随机数生成器。要求是:

  1. 我不希望每次使用它时都创建一个discrete_distribution对象。我知道分配对象是轻量级的,但我的重量阵列太长,以至于成本仍然太高。另外,我需要在这个类的不同函数中使用分发对象。
  2. 我需要不时更改分布(权重数组)
  3. 我不知道构建类时的确切分布(权重数组)
  4. 目前我有两个解决方案,在类中使用random_device rd; mt19937 engine;初始化随机数引擎,并在初始化列表中初始化engine(rd())

    一种是使用discrete_distribution<> *d=new discrete_distribution<>(weight_array,weight_array+weight_array_size)创建discrete_distribution对象并将指针存储在类中。每次我调用(* d)(引擎)生成一个随机数,我只需删除该分布并创建一个新的更新权重数组。

    另一种方法是在类中定义discrete_distribution<> d并使用d=discrete_distribution<>(weight_array,weight_array+weight_array_size)更新权重数组,这样我们就可以使用d(engine)生成随机数,而不需要担心指针。< / p>

    但似乎两种方式都不是使用c ++对象的经典方式。他们错了吗?以这种方式编写代码有什么缺点吗?

    由于

1 个答案:

答案 0 :(得分:0)

  

另一种方法是在类中定义discrete_distribution<> d并使用d=discrete_distribution<>(weight_array,weight_array+weight_array_size)更新权重数组,这样我们就可以使用d(engine)生成随机数,而不需要担心指针。< / p>

这是处理对象实例的完美的常用C ++风格。

事实上,许多类型没有修饰符成员,因为它们是可分配的。

在这种情况下,您可以使用params()成员更改权重:

<强> Live On Coliru

#include <boost/random.hpp>
#include <boost/random/random_device.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <iostream>

namespace br = boost::random;

struct X {
    using Weight = double;
    br::mt19937                            engine { br::random_device{}() };
    br::discrete_distribution<int, Weight> dist   { {0.2, 0.2, 0.2, 0.2, 0.2} };

    void sample() {
        for (auto i : {1,2,3,4})
            std::cout << "#" << i << ":" << dist(engine) << " ";
        std::cout << "\n";
    }

    void show_probabilities() {
        boost::copy(dist.param().probabilities(), std::ostream_iterator<Weight>(std::cout << "probabilities: ", " "));
        std::cout << "\n";
    }

    void reprogram(std::initializer_list<Weight> probabilities) {
        dist.param(probabilities);
    }
};

int main() {
    X x;
    x.show_probabilities();
    x.sample();

    x.reprogram({0.01, 0.99});

    x.show_probabilities();
    x.sample();
}

打印类似

的内容
probabilities: 0.2 0.2 0.2 0.2 0.2 
#1:1 #2:2 #3:0 #4:4 
probabilities: 0.01 0.99 
#1:1 #2:1 #3:1 #4:1