Я пишу дискретный генератор случайных чисел в классе C ++. Требования следующие:
В настоящее время у меня есть два решения, после инициализации двигателя случайных чисел с random_device rd; mt19937 engine;
в классе и engine(rd())
в списке инициализации.
Одним из них является создание объекта discrete_distribution с discrete_distribution<> *d=new discrete_distribution<>(weight_array,weight_array+weight_array_size)
и сохранить указатель в классе. Каждый раз, когда я вызываю (* d) (engine), чтобы сгенерировать случайное число, мне просто нужно удалить распределение и создать новое для обновления массива весов.
Другой способ — определить discrete_distribution<> d
в классе и обновите массив веса с d=discrete_distribution<>(weight_array,weight_array+weight_array_size)
, так что мы можем сгенерировать случайное число с d(engine)
и не нужно беспокоиться о указателях.
Но кажется, что оба способа не являются классическим способом использования объектов C ++. Они не правы? Есть ли недостатки для написания кода таким образом?
Спасибо
Другой способ — определить
discrete_distribution<> d
в классе и обновите массив веса сd=discrete_distribution<>(weight_array,weight_array+weight_array_size)
, так что мы можем сгенерировать случайное число сd(engine)
и не нужно беспокоиться о указателях.
Это прекрасно, общий стиль C ++ для работы с экземплярами объектов.
На самом деле многие типы не имеют членов-модификаторов, потому что они назначаются.
В этом случае вы можете, однако, использовать params()
Член для изменения веса:
#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
Других решений пока нет …