15 #ifndef PAAL_LP_BASE_HPP
16 #define PAAL_LP_BASE_HPP
22 #include <boost/range/iterator_range.hpp>
26 #include <unordered_map>
27 #include <unordered_set>
56 using RowSet = std::unordered_set<row_id>;
57 using ColSet = std::unordered_set<col_id>;
58 using RowNames = std::unordered_map<row_id, std::string>;
59 using ColNames = std::unordered_map<col_id, std::string>;
63 using RowIter = RowSet::const_iterator;
64 using ColIter = ColSet::const_iterator;
69 lp_base(
const std::string problem_name =
"",
71 :
LP(), m_problem_name(problem_name) {
72 LP::set_optimization_type(opt_type);
79 m_problem_name = problem_name;
93 double ub = lp_traits::PLUS_INF,
94 const std::string &name =
"") {
96 m_col_ids.insert(colId);
97 m_col_names.insert(std::make_pair(colId, name));
111 const std::string &name =
"") {
113 m_row_ids.insert(rowId);
114 m_row_names.insert(std::make_pair(rowId, name));
132 auto it = m_col_names.find(col);
133 assert(it != m_col_names.end());
141 auto it = m_row_names.find(row);
142 assert(it != m_row_names.end());
155 m_col_names.erase(*col);
156 return m_col_ids.erase(col);
166 m_col_names.erase(col);
167 std::size_t nr = m_col_ids.erase(col);
180 m_row_names.erase(*row);
181 return m_row_ids.erase(row);
191 m_row_names.erase(row);
192 std::size_t nr = m_row_ids.erase(row);
200 for (
auto &&row : m_row_ids) {
206 for (
auto &&col : m_col_ids) {
221 const RowSet &
get_rows()
const {
return m_row_ids; }
231 LP::get_col_lower_bound(col)),
232 LP::get_col_upper_bound(col));
240 return boost::distance(LP::get_rows_in_column(col));
247 return LP::get_row_expression(row).non_zeros();
256 auto expr = LP::get_row_expression(row);
257 auto ids = expr.get_elements();
258 return get_row_sum_for_ids(ids.begin(), ids.end());
264 template <
typename ostream>
265 friend ostream &operator<<(ostream &o, const lp_base<LP> &lp) {
266 o <<
"Problem name: " << lp.m_problem_name << std::endl;
267 auto get_name = [&](
col_id col) {
268 auto name =
" " + lp.get_col_name(col);
270 name = detail::col_id_to_string(col);
275 o << std::endl <<
"Objective function:" << std::endl;
277 o, lp.get_columns() | boost::adaptors::transformed([&](
col_id col) {
282 o << std::endl << std::endl <<
"Columns:" << std::endl;
283 for (
auto col : lp.get_columns()) {
284 o << lp.get_col_lower_bound(col) <<
" <= " << get_name(col)
285 <<
" <= " << lp.get_col_upper_bound(col) << std::endl;
287 o << std::endl <<
"Rows:" << std::endl;
289 for (
auto row : lp.get_rows()) {
290 auto cols = lp.get_row_expression(row);
291 if (cols.non_zeros() == 0) {
294 o <<
"Row " << lp.get_row_name(row) << std::endl;
295 print_double_bounded_expression(
297 lp.get_row_lower_bound(row),
298 lp.get_row_upper_bound(row)),
300 o << std::endl << std::endl;
302 o << std::endl <<
"Current solution: " << std::endl;
304 o, lp.get_columns() | boost::adaptors::transformed([&](
col_id col) {
305 return get_name(col) +
" = " +
318 template <
typename Iter>
319 double get_row_sum_for_ids(Iter begin, Iter end)
const {
320 return std::accumulate(
321 begin, end, 0., [ = ](
double sum, std::pair<col_id, double> col) {
327 std::string m_problem_name;
332 ColNames m_col_names;
333 RowNames m_row_names;
340 #endif // PAAL_LP_BASE_HPP
The common LP solvers base class. Responsible for:
col_id add_column(double cost_coef=0, double lb=0., double ub=lp_traits::PLUS_INF, const std::string &name="")
double get_row_sum(row_id row) const
std::string pretty_to_string(double x, double epsilon=1e-9)
pretty_to_string prints double which is close to int as int
void print_collection(Stream &o, Range &&r, const std::string &del)
prints collection with delimiters without trailing delimiter
int get_col_degree(col_id col) const
void set_lp_name(const std::string problem_name)
std::string get_row_name(row_id row) const
RowIter delete_row(RowIter row)
simplex_type
simplex method type
lp_base(const std::string problem_name="", optimization_type opt_type=MINIMIZE)
int get_row_degree(row_id row) const
optimization_type
optimization type
void delete_col(col_id col)
int columns_number() const
std::string get_col_name(col_id col) const
ColIter delete_col(ColIter col)
const ColSet & get_columns() const
double get_col_value(col_id col) const
row_id add_row(const double_bounded_expression &constraint=double_bounded_expression{}, const std::string &name="")
const RowSet & get_rows() const
void delete_row(row_id row)