Как повторно использовать и повторно инициализировать c ++ discrete_distribution в классе?

Я пишу дискретный генератор случайных чисел в классе C ++. Требования следующие:

  1. Я не хочу создавать объект discrete_distribution каждый раз, когда я его использую. Я знаю, что объект распределения легкий, но мой массив весов настолько длинный, что стоимость все еще слишком высока. Кроме того, мне нужно использовать объект распределения в различных функциях этого класса.
  2. Мне нужно время от времени менять распределение (весовой массив)
  3. Я не знаю точное распределение (весовой массив), когда класс построен

В настоящее время у меня есть два решения, после инициализации двигателя случайных чисел с 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 ++. Они не правы? Есть ли недостатки для написания кода таким образом?

Спасибо

2

Решение

Другой способ — определить 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
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]