3

I am writing a discrete distribution random number generator in a c++ class. The requirements are:

  1. I don't want to create a discrete_distribution object each time I use it. I know distribution object is lightweight, but my weight array is so long that the cost is still too high. Also, I need to use the distribution object in different functions in this class.
  2. I need to change the distribution (weight array) from time to time
  3. I don't know the exact distribution (weight array) when the class is constructed

Currently I have two solutions, after initialize random number engine with random_device rd; mt19937 engine; in class and engine(rd()) in initialize list.

One is to create the discrete_distribution object with discrete_distribution<> *d=new discrete_distribution<>(weight_array,weight_array+weight_array_size) and store the pointer in the class. Each time I call (*d)(engine) to generate a random number, and I just need to delete the distribution and make a new one to update the weight array.

Another way is to define discrete_distribution<> d in class and update weight array with d=discrete_distribution<>(weight_array,weight_array+weight_array_size), so that we can generate random number with d(engine) and don't need to worry about pointers.

But it seems that both ways are not classical way to use c++ objects. Are they wrong? Are there any drawbacks to write code this way?

Thanks

4

1 回答 1

0

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

这是处理对象实例的完美通用 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 
于 2017-08-24T07:57:26.363 回答