我正在c ++类中编写一个离散分布随机数生成器。要求是:
目前我有两个解决方案,在类中使用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 ++对象的经典方式。他们错了吗?以这种方式编写代码有什么缺点吗?
由于
答案 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