delpi  0.0.1
DElta-complete LP solver
Loading...
Searching...
No Matches
LpSolver.h
1
7#pragma once
8
9#include <iosfwd>
10#include <memory>
11#include <span>
12#include <string>
13#include <unordered_map>
14#include <utility>
15#include <vector>
16
17#include "delpi/libs/gmp.h"
18#include "delpi/solver/Column.h"
19#include "delpi/solver/LpResult.h"
20#include "delpi/solver/LpRowSense.h"
21#include "delpi/solver/LpStats.h"
22#include "delpi/solver/Row.h"
23#include "delpi/symbolic/Expression.h"
24#include "delpi/symbolic/Formula.h"
25#include "delpi/symbolic/Variable.h"
26#include "delpi/util/Config.h"
27#include "delpi/util/Stats.h"
28#include "delpi/util/concepts.h"
29
30namespace delpi {
31
60class LpSolver {
61 public:
62 using ColumnIndex = int;
63 using RowIndex = int;
78 std::function<void(const LpSolver& lp_solver, LpResult result, const std::vector<mpq_class>& x,
79 const std::vector<mpq_class>& y, const mpq_class& obj_lb, const mpq_class& obj_ub)>;
95 std::function<bool(const LpSolver& lp_solver, LpResult result, const std::vector<mpq_class>& x,
96 const std::vector<mpq_class>& y, const mpq_class& obj_lb, const mpq_class& obj_ub)>;
97
98 static std::unique_ptr<LpSolver> GetInstance(const Config& config);
99
107 LpSolver(mpq_class ninfinity, mpq_class infinity, Config config = {}, const std::string& class_name = "LpSolver");
108 virtual ~LpSolver() = default;
109
116 bool Parse();
124 bool ParseFile(const std::string& filename);
132 bool ParseString(const std::string& string);
141 bool ParseStream(std::istream& stream, const std::string& stream_name = "(stdin)");
142
144 [[nodiscard]] virtual int num_columns() const = 0;
146 [[nodiscard]] virtual int num_rows() const = 0;
148 [[nodiscard]] const mpq_class& ninfinity() const { return ninfinity_; }
150 [[nodiscard]] const mpq_class& infinity() const { return infinity_; }
152 [[nodiscard]] const LpStats& stats() const { return stats_; }
154 [[nodiscard]] const Config& config() const { return config_; }
156 [[nodiscard]] const std::vector<mpq_class>& solution() const { return solution_; }
158 [[nodiscard]] const std::vector<mpq_class>& dual_solution() const { return dual_solution_; }
160 [[nodiscard]] const mpq_class& obj_lb() const { return obj_lb_; }
162 [[nodiscard]] const mpq_class& obj_ub() const { return obj_ub_; }
164 [[nodiscard]] bool is_min() const { return is_min_; }
165
167 [[nodiscard]] const std::unordered_map<Variable, int>& var_to_col() const { return var_to_col_; }
169 [[nodiscard]] const std::vector<Variable>& variables() const { return col_to_var_; }
171 [[nodiscard]] std::vector<Formula> constraints() const;
173 [[nodiscard]] LpResult expected() const;
175 [[nodiscard]] std::unordered_map<Variable, mpq_class> model() const;
177 [[nodiscard]] const SolveCallback& solve_cb() const { return solve_cb_; }
179 [[nodiscard]] SolveCallback& m_solve_cb() { return solve_cb_; }
181 [[nodiscard]] const PartialSolveCallback& partial_solve_cb() const { return partial_solve_cb_; }
183 [[nodiscard]] PartialSolveCallback& m_partial_solve_cb() { return partial_solve_cb_; }
185 [[nodiscard]] const std::unordered_map<std::string, std::string>& info() const { return info_; }
186
192 [[nodiscard]] std::unordered_map<Variable, mpq_class> model(const std::vector<mpq_class>& x) const;
198 [[nodiscard]] const mpq_class& solution(const Variable var) const { return solution_.at(var_to_col_.at(var)); }
199
205 [[nodiscard]] const Variable& var(const int column) const { return col_to_var_.at(column); }
211 [[nodiscard]] virtual Column column(int column_idx) const = 0;
217 [[nodiscard]] virtual Row row(int row_idx) const = 0;
224 virtual void ReserveColumns(int size);
231 virtual void ReserveRows(int size);
232
238 const std::string& GetInfo(const std::string& key) const;
244 void SetInfo(const std::string& key, const std::string& value);
273 void SetOption(const std::string& key, const std::string& value);
274
281 virtual void AddColumns(const std::span<Column>& columns);
289 ColumnIndex AddColumn(const Column& column);
295 ColumnIndex AddColumn(const Variable& var);
303 ColumnIndex AddColumn(const Variable& var, const mpq_class& obj);
311 ColumnIndex AddColumn(const Variable& var, const mpq_class& lb, const mpq_class& ub);
322 virtual ColumnIndex AddColumn(const Variable& var, const mpq_class& obj, const mpq_class& lb,
323 const mpq_class& ub) = 0;
324
330 virtual void AddRows(const std::span<Row>& rows);
339 RowIndex AddRow(const Row& row);
349 virtual RowIndex AddRow(const std::vector<std::pair<Variable, mpq_class>>& addends, const mpq_class& lb,
350 const mpq_class& ub) = 0;
355 RowIndex AddRow(const Formula& formula);
369 RowIndex AddRow(const Expression& lhs, FormulaKind sense, const mpq_class& rhs);
383 virtual RowIndex AddRow(const Expression::Addends& lhs, FormulaKind sense, const mpq_class& rhs) = 0;
384
391 virtual void SetCoefficient(RowIndex row, ColumnIndex column, const mpq_class& value) = 0;
392
397 void SetObjective(const Expression& objective);
402 void SetObjective(const std::unordered_map<int, mpq_class>& objective);
407 void SetObjective(const std::vector<mpq_class>& objective);
413 void SetObjective(const Variable& var, const mpq_class& value);
419 virtual void SetObjective(int column, const mpq_class& value) = 0;
420
427 virtual void SetBound(Variable var, const mpq_class& lb, const mpq_class& ub) = 0;
428
441 LpResult Solve();
442
449 void Maximise(const Expression& objective_function);
457 template <TypedIterable<std::pair<const Variable, mpq_class>> T>
458 void Maximise(const T& objective_function);
465 void Minimise(const Expression& objective_function);
473 template <TypedIterable<std::pair<const Variable, mpq_class>> T>
474 void Minimise(const T& objective_function);
475
477 void ResetObjective();
478
485 [[nodiscard]] bool CheckAgainstExpected(LpResult result) const;
486
492 bool Verify() const;
493
494#ifndef NDEBUG
495 virtual void Dump() = 0;
496#endif
497
498 protected:
503 void EnsureSense(bool is_min);
504
506 virtual void EnsureSenseCore() = 0;
507
516 virtual LpResult SolveCore() = 0;
517
530 bool SetSimpleBoundInsteadOfAddRow(const std::vector<Expression::Addend>& addends, const mpq_class& lb,
531 const mpq_class& ub);
532
535 std::unordered_map<std::string, std::string> info_;
536
537 std::unordered_map<Variable, int> var_to_col_;
540 std::vector<Variable> col_to_var_;
543 std::vector<mpq_class> solution_;
544 std::vector<mpq_class> dual_solution_;
545 mpq_class obj_lb_;
546 mpq_class obj_ub_;
547
550
551 bool is_min_;
552 mpq_class ninfinity_;
553 mpq_class infinity_;
554};
555
556std::ostream& operator<<(std::ostream& os, const LpSolver& solver);
557
558} // namespace delpi
559
560#ifdef DELPI_INCLUDE_FMT
561
562#include "delpi/util/logging.h"
563
564OSTREAM_FORMATTER(delpi::LpSolver);
565
566#endif
Simple dataclass used to store the configuration of the program.
Definition Config.h:36
Represents a symbolic form of an expression.
Definition Expression.h:37
Symbolic formula used to represent a constraint in the LP problem.
Definition Formula.h:32
Facade class that hides the underlying LP solver used by delpi.
Definition LpSolver.h:60
virtual void SetCoefficient(RowIndex row, ColumnIndex column, const mpq_class &value)=0
Set the coefficient of the row constraint to apply at the column decisional variable.
virtual RowIndex AddRow(const Expression::Addends &lhs, FormulaKind sense, const mpq_class &rhs)=0
Add a new row to the LP problem with the given lhs linear summation, sense and rhs.
virtual void ReserveColumns(int size)
Reserve space for the given number of columns and rows.
Definition LpSolver.cpp:159
const Variable & var(const int column) const
Shorthand notation to get the real variable linked with column column.
Definition LpSolver.h:205
void SetObjective(const Expression &objective)
Set the objective coefficients of the LP problem to the given objective.
Definition LpSolver.cpp:191
bool SetSimpleBoundInsteadOfAddRow(const std::vector< Expression::Addend > &addends, const mpq_class &lb, const mpq_class &ub)
Check whether the row that is about to be added is a simple bound.
Definition LpSolver.cpp:275
mpq_class infinity_
Infinity threshold value.
Definition LpSolver.h:553
PartialSolveCallback partial_solve_cb_
Callback to call after solving the LP problem with a partial solution.
Definition LpSolver.h:549
bool is_min_
Whether this is a minimization or maximization LP problem.
Definition LpSolver.h:551
mpq_class ninfinity_
Negative infinity threshold value.
Definition LpSolver.h:552
RowIndex AddRow(const Row &row)
Add a new row to the LP problem with the given row.
Definition LpSolver.cpp:112
void SetInfo(const std::string &key, const std::string &value)
Set the information stored under the given key to the given value.
Definition LpSolver.cpp:165
Config config_
Configuration to use.
Definition LpSolver.h:533
virtual Column column(int column_idx) const =0
Get the column at the given column_idx index.
SolveCallback solve_cb_
Callback to call after solving the LP problem.
Definition LpSolver.h:548
const std::unordered_map< std::string, std::string > & info() const
@getter{information stored in the LP solver}
Definition LpSolver.h:185
virtual void SetObjective(int column, const mpq_class &value)=0
The the objective coefficient of the given column to the given value.
virtual LpResult SolveCore()=0
Internal method that optimises the LP problem with the given delta.
bool CheckAgainstExpected(LpResult result) const
Check whether the result obtained by the solver is compatible with the one collected from the file.
Definition LpSolver.cpp:243
bool Parse()
Parse the input file or stdin based on the Config parameters.
Definition parser.cpp:19
std::vector< mpq_class > solution_
Solution vector.
Definition LpSolver.h:543
std::unordered_map< Variable, int > var_to_col_
Theory column ⇔ Variable.
Definition LpSolver.h:537
mpq_class obj_ub_
Upper bound on the objective value, if any.
Definition LpSolver.h:546
bool Verify() const
Verify that the current solution_ satisfies all the constraints in the LpSolver.
Definition LpSolver.cpp:261
std::vector< mpq_class > dual_solution_
Dual solution vector.
Definition LpSolver.h:544
virtual void AddColumns(const std::span< Column > &columns)
Add a vector of columns to the LP problem.
Definition LpSolver.cpp:218
const mpq_class & solution(const Variable var) const
Get the value of var in the solution vector.
Definition LpSolver.h:198
virtual ColumnIndex AddColumn(const Variable &var, const mpq_class &obj, const mpq_class &lb, const mpq_class &ub)=0
Add a new bounded column to the LP problem, ensuring that the variable var is in the range and has t...
void EnsureSense(bool is_min)
Make sure the LP solvers are aware of the sense of the LP problem (minimisation or maximisation).
Definition LpSolver.cpp:271
virtual void AddRows(const std::span< Row > &rows)
Add a vector of rows to the LP problem.
Definition LpSolver.cpp:108
mpq_class obj_lb_
Lower bound on the objective value, if any.
Definition LpSolver.h:545
void Maximise(const Expression &objective_function)
Set the objective_function to maximise while being subject to all the constraints.
Definition LpSolver.cpp:217
std::vector< Variable > col_to_var_
Literal ⇔ lp row.
Definition LpSolver.h:540
ColumnIndex AddColumn(const Column &column)
Add a new column to the LP problem.
Definition LpSolver.cpp:88
void Minimise(const Expression &objective_function)
Set the objective_function to minimise while being subject to all the constraints.
Definition LpSolver.cpp:230
bool ParseStream(std::istream &stream, const std::string &stream_name="(stdin)")
Parse the given stream as input.
Definition parser.cpp:25
LpSolver(mpq_class ninfinity, mpq_class infinity, Config config={}, const std::string &class_name="LpSolver")
Construct a new LpSolver object with the given config.
Definition LpSolver.cpp:41
bool ParseFile(const std::string &filename)
Parse the file with the given filename.
Definition parser.cpp:20
std::function< bool(const LpSolver &lp_solver, LpResult result, const std::vector< mpq_class > &x, const std::vector< mpq_class > &y, const mpq_class &obj_lb, const mpq_class &obj_ub)> PartialSolveCallback
Callback invoked by the LP solver when a solution (or delta solution) is found.
Definition LpSolver.h:94
virtual void EnsureSenseCore()=0
Make sure the LP solvers are aware of the sense of the LP problem (minimisation or maximisation).
void SetOption(const std::string &key, const std::string &value)
Set the option identified by the given key to the given value.
Definition LpSolver.cpp:166
std::unordered_map< std::string, std::string > info_
Generic information map. Generally collected from the file.
Definition LpSolver.h:535
virtual void SetBound(Variable var, const mpq_class &lb, const mpq_class &ub)=0
Set the bounds of a var in the LP problem to the given lb and ub.
virtual RowIndex AddRow(const std::vector< std::pair< Variable, mpq_class > > &addends, const mpq_class &lb, const mpq_class &ub)=0
Add a new row to the LP problem with the given addends bounded by lb and ub.
LpStats stats_
Statistics of the solver.
Definition LpSolver.h:534
virtual void ReserveRows(int size)
Reserve space for the given number of rows.
Definition LpSolver.cpp:162
std::function< void(const LpSolver &lp_solver, LpResult result, const std::vector< mpq_class > &x, const std::vector< mpq_class > &y, const mpq_class &obj_lb, const mpq_class &obj_ub)> SolveCallback
Callback invoked by the LP solver when a solution (or delta solution) is found.
Definition LpSolver.h:77
void ResetObjective()
Set all coefficients in the objective function to zero.
Definition LpSolver.cpp:239
const std::string & GetInfo(const std::string &key) const
Retrieve the information stored under the given key.
Definition LpSolver.cpp:164
LpResult Solve()
Optimise the LP problem with the given delta.
Definition LpSolver.cpp:203
virtual Row row(int row_idx) const =0
Get the row at the given row_idx index.
bool ParseString(const std::string &string)
Parse the given string as input.
Definition parser.cpp:32
Real symbolic variable.
Definition Variable.h:20
Global namespace for the delpi library.
LpResult
Possible outcomes of the LP solver.
Definition LpResult.h:14
FormulaKind
Kinds of symbolic formulas.
Definition FormulaKind.h:14
Convenient structure representing a column in the LP solver.
Definition Column.h:23
Collection of statistics for the LP solver.
Definition LpStats.h:17
Structure representing a row in the LP solver in the form of a linear combination of variables.
Definition Row.h:24