【问题标题】:How to reuse and reinitialize c++ discrete_distribution in class?如何在类中重用和重新初始化 c++ 离散分布?
【发布时间】:2017-08-24 02:56:43
【问题描述】:

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

  1. 我不想在每次使用时都创建一个discrete_distribution 对象。我知道分发对象是轻量级的,但是我的权重数组太长了,成本仍然太高。另外,我需要在这个类的不同函数中使用分布对象。
  2. 我需要不时更改分布(权重数组)
  3. 不知道类构建时的准确分布(权重数组)

目前我有两种解决方案,在类中使用random_device rd; mt19937 engine; 初始化随机数引擎,在初始化列表中使用engine(rd())

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

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

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

谢谢

【问题讨论】:

    标签: c++ random boost boost-random


    【解决方案1】:

    另一种方法是在类中定义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 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      相关资源
      最近更新 更多