Проблемы с std :: piecewise_constant_distribution и std :: vector

Учитывая кучу строк, я пытаюсь создать программу, которая может имитировать псевдослучайное поведение с взвешенным распределением на основе моего ввода.

До сих пор я придумал это

#include <iostream>
#include <random>
#include <type_traits>
#include <map>
#include <vector>
#include <string>
#include <initializer_list>

#define N 100

int main()
{
std::vector<std::string> interval{"Bread", "Castle", "Sun"};
std::vector<float> weights { 0.40f, 0.50f, 0.10f };
std::piecewise_constant_distribution<> dist(interval.begin(),
interval.end(),
weights.begin());

std::random_device rd;
std::mt19937 gen(rd()) ;

for(int i = 0; i<N;i++)
{
std::cout << dist(gen) << "\n";
}

return(0);

}

Но эта вещь не работает, и я понятия не имею, почему, обычное использование std::piecewise_constant_distribution Согласно онлайн-примерам, это с std::arrays, но я пытаюсь реализовать это с помощью std::vectorЭто главное отличие, которое я нашел.

С Clang ++ вывод ошибки

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/random.tcc:2409:10: error: no matching member function for
call to 'push_back'
_M_int.push_back(*__bbegin);
~~~~~~~^~~~~~~~~

но я не могу понять это, потому что нет явного .push_back в моем коде я также не понимаю, что происходит, потому что отладка шаблонного класса — это кошмар, и я только начинаю с этого.

У кого-нибудь есть идеи, почему код не работает?

2

Решение

Тип результата по умолчанию std::piecewise_constant_distribution является RealType (double Вот). Похоже, вы пытаетесь выбрать из 3 string варианты с разным весом, но это не то, что std::piecewise_constant_distribution для. Он предназначен для генерации случайных случайных значений из числовой интервалы с заданным весом. Если вы измените свой пример и измените interval чтобы:

std::vector<double> interval {1, 3, 5, 10, 15, 20};

Все скомпилируется счастливо. Судя по всему, вы хотите std::discrete_distribution:

...

std::vector<std::string> interval{"Bread", "Castle", "Sun"};
std::vector<float> weights { 0.40f, 0.50f, 0.10f };
std::discrete_distribution<> dist(weights.begin(), weights.end());

std::mt19937 gen(rd());

for(int i = 0; i<N;i++)
{
std::cout << interval[dist(gen)] << "\n";
}

...
3

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

template< class RealType = double >
class piecewise_constant_distribution;

работает на RealType, не может работать со строками. посмотреть здесь

производит случайные числа с плавающей точкой, которые равномерно
распределены в каждом из нескольких подинтервалов [bi, bi + 1), каждый
со своим собственным весом

измените это, чтобы быть:

std::vector<float> weights { 0.40f, 0.50f, 0.10f };
std::discrete_distribution<> dist(weights.begin(), weights.end());

std::mt19937 gen(rd());

for(int i = 0; i<N;i++)
{
std::cout << interval[dist(gen)] << "\n";
}

и вы сделали.


СОВЕТ:
читать сообщения, созданные вашим другом компилятором

In file included from /usr/include/c++/4.7/random:51:0,
from prog.cpp:2:
/usr/include/c++/4.7/bits/random.tcc: In instantiation of ‘std::piecewise_constant_distribution<_RealType>::param_type::param_type(_InputIteratorB, _InputIteratorB, _InputIteratorW) [with _InputIteratorB = __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >; _InputIteratorW = __gnu_cxx::__normal_iterator<float*, std::vector<float> >; _RealType = double]’:
/usr/include/c++/4.7/bits/random.h:4940:39:   required from ‘std::piecewise_constant_distribution<_RealType>::piecewise_constant_distribution(_InputIteratorB, _InputIteratorB, _InputIteratorW) [with _InputIteratorB = __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >; _InputIteratorW = __gnu_cxx::__normal_iterator<float*, std::vector<float> >; _RealType = double]’
prog.cpp:17:64:   required from here
/usr/include/c++/4.7/bits/random.tcc:2407:3: error: no matching function for call to ‘std::vector<double>::push_back(std::basic_string<char>&)’
/usr/include/c++/4.7/bits/random.tcc:2407:3: note: candidates are:
In file included from /usr/include/c++/4.7/vector:65:0,
from /usr/include/c++/4.7/bits/random.h:34,
from /usr/include/c++/4.7/random:50,
from prog.cpp:2:
/usr/include/c++/4.7/bits/stl_vector.h:881:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = double; _Alloc = std::allocator<double>; std::vector<_Tp, _Alloc>::value_type = double]
/usr/include/c++/4.7/bits/stl_vector.h:881:7: note:   no known conversion for argument 1 from ‘std::basic_string<char>’ to ‘const value_type& {aka const double&}’
/usr/include/c++/4.7/bits/stl_vector.h:899:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = double; _Alloc = std::allocator<double>; std::vector<_Tp, _Alloc>::value_type = double]
/usr/include/c++/4.7/bits/stl_vector.h:899:7: note:   no known conversion for argument 1 from ‘std::basic_string<char>’ to ‘std::vector<double>::value_type&& {aka double&&}’

увидеть?

неизвестное преобразование для аргумента 1 из ‘std :: basic_string ’ в
«Станд :: вектор :: value_type&& {ака двойной&&}»

все рассказывает.

1

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