13#include <unordered_map>
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"
62 using ColumnIndex = 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)>;
98 static std::unique_ptr<LpSolver> GetInstance(
const Config& config);
107 LpSolver(mpq_class ninfinity, mpq_class infinity,
Config config = {},
const std::string& class_name =
"LpSolver");
124 bool ParseFile(
const std::string& filename);
141 bool ParseStream(std::istream& stream,
const std::string& stream_name =
"(stdin)");
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_; }
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;
185 [[nodiscard]]
const std::unordered_map<std::string, std::string>&
info()
const {
return info_; }
192 [[nodiscard]] std::unordered_map<Variable, mpq_class> model(
const std::vector<mpq_class>& x)
const;
217 [[nodiscard]]
virtual Row row(
int row_idx)
const = 0;
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);
281 virtual void AddColumns(
const std::span<Column>& columns);
323 const mpq_class& ub) = 0;
330 virtual void AddRows(
const std::span<Row>& rows);
349 virtual RowIndex
AddRow(
const std::vector<std::pair<Variable, mpq_class>>& addends,
const mpq_class& lb,
350 const mpq_class& ub) = 0;
383 virtual RowIndex
AddRow(
const Expression::Addends& lhs,
FormulaKind sense,
const mpq_class& rhs) = 0;
402 void SetObjective(
const std::unordered_map<int, mpq_class>& objective);
407 void SetObjective(
const std::vector<mpq_class>& objective);
457 template <TypedIterable<std::pair<const Variable, mpq_
class>> T>
458 void Maximise(
const T& objective_function);
473 template <TypedIterable<std::pair<const Variable, mpq_
class>> T>
474 void Minimise(
const T& objective_function);
495 virtual void Dump() = 0;
531 const mpq_class& ub);
535 std::unordered_map<std::string, std::string>
info_;
556std::ostream& operator<<(std::ostream& os,
const LpSolver& solver);
560#ifdef DELPI_INCLUDE_FMT
562#include "delpi/util/logging.h"
Simple dataclass used to store the configuration of the program.
Represents a symbolic form of an expression.
Facade class that hides the underlying LP solver used by delpi.
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.
const Variable & var(const int column) const
Shorthand notation to get the real variable linked with column column.
void SetObjective(const Expression &objective)
Set the objective coefficients of the LP problem to the given objective.
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.
mpq_class infinity_
Infinity threshold value.
PartialSolveCallback partial_solve_cb_
Callback to call after solving the LP problem with a partial solution.
bool is_min_
Whether this is a minimization or maximization LP problem.
mpq_class ninfinity_
Negative infinity threshold value.
RowIndex AddRow(const Row &row)
Add a new row to the LP problem with the given row.
void SetInfo(const std::string &key, const std::string &value)
Set the information stored under the given key to the given value.
Config config_
Configuration to use.
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.
const std::unordered_map< std::string, std::string > & info() const
@getter{information stored in the LP solver}
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.
bool Parse()
Parse the input file or stdin based on the Config parameters.
std::vector< mpq_class > solution_
Solution vector.
std::unordered_map< Variable, int > var_to_col_
Theory column ⇔ Variable.
mpq_class obj_ub_
Upper bound on the objective value, if any.
bool Verify() const
Verify that the current solution_ satisfies all the constraints in the LpSolver.
std::vector< mpq_class > dual_solution_
Dual solution vector.
virtual void AddColumns(const std::span< Column > &columns)
Add a vector of columns to the LP problem.
const mpq_class & solution(const Variable var) const
Get the value of var in the solution vector.
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).
virtual void AddRows(const std::span< Row > &rows)
Add a vector of rows to the LP problem.
mpq_class obj_lb_
Lower bound on the objective value, if any.
void Maximise(const Expression &objective_function)
Set the objective_function to maximise while being subject to all the constraints.
std::vector< Variable > col_to_var_
Literal ⇔ lp row.
ColumnIndex AddColumn(const Column &column)
Add a new column to the LP problem.
void Minimise(const Expression &objective_function)
Set the objective_function to minimise while being subject to all the constraints.
bool ParseStream(std::istream &stream, const std::string &stream_name="(stdin)")
Parse the given stream as input.
LpSolver(mpq_class ninfinity, mpq_class infinity, Config config={}, const std::string &class_name="LpSolver")
Construct a new LpSolver object with the given config.
bool ParseFile(const std::string &filename)
Parse the file with the given filename.
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.
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.
std::unordered_map< std::string, std::string > info_
Generic information map. Generally collected from the file.
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.
virtual void ReserveRows(int size)
Reserve space for the given number of rows.
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.
void ResetObjective()
Set all coefficients in the objective function to zero.
const std::string & GetInfo(const std::string &key) const
Retrieve the information stored under the given key.
LpResult Solve()
Optimise the LP problem with the given delta.
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.
Global namespace for the delpi library.
LpResult
Possible outcomes of the LP solver.
FormulaKind
Kinds of symbolic formulas.
Convenient structure representing a column in the LP solver.
Collection of statistics for the LP solver.
Structure representing a row in the LP solver in the form of a linear combination of variables.