简体   繁体   English

如何在类中重用和重新初始化C ++ Distributed_distribution?

[英]How to reuse and reinitialize c++ discrete_distribution in class?

I am writing a discrete distribution random number generator in a c++ class. 我正在c ++类中编写离散分布随机数生成器。 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; 当前我有两种解决方案,用random_device rd; mt19937 engine;初始化随机数引擎之后random_device rd; mt19937 engine; random_device rd; mt19937 engine; in class and engine(rd()) in initialize list. 在类中,并且在初始化列表中包含engine(rd())

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. 一种方法是使用discrete_distribution<> *d=new discrete_distribution<>(weight_array,weight_array+weight_array_size)创建离散量分布对象并将指针存储在类中。 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. 每次我调用(* d)(engine)生成一个随机数时,我只需要删除分布并制作一个新值来更新权重数组。

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

But it seems that both ways are not classical way to use c++ objects. 但是似乎这两种方式都不是使用c ++对象的经典方式。 Are they wrong? 他们错了吗? Are there any drawbacks to write code this way? 用这种方式编写代码有什么缺点吗?

Thanks 谢谢

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

This is perfectly fine, common C++ style to deal with object instances. 这是一种很好的通用C ++样式来处理对象实例。

In fact many types do not have modifier members because they are assignable. 实际上,许多类型没有修饰符成员,因为它们是可分配的。

In this case you could, however use the params() member to change the weights: 在这种情况下,您可以使用params()成员更改权重:

Live On Coliru 生活在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();
}

Printing something like 打印类似

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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM