13#include "delpi/libs/eigen.h"
14#include "delpi/libs/gmp.h"
15#include "delpi/solver/LpSolver.h"
16#include "delpi/solver/internal/Basis.h"
17#include "delpi/symbolic/Expression.h"
18#include "delpi/symbolic/Variable.h"
19#include "internal/LpProblem.h"
29 explicit DelpiLpSolver(
Config config = {},
const std::string& class_name =
"DelpiLpSolver");
31 [[nodiscard]]
int num_columns()
const override;
32 [[nodiscard]]
int num_rows()
const override;
33 [[nodiscard]]
const internal::LpProblem& problem()
const {
return problem_; }
35 [[nodiscard]]
Column column(ColumnIndex column_idx)
const override;
36 [[nodiscard]]
Row row(RowIndex row_idx)
const override;
39 ColumnIndex
AddColumn(
const Variable&
var,
const mpq_class& obj,
const mpq_class& lb,
const mpq_class& ub)
override;
40 RowIndex AddRow(
const std::vector<Expression::Addend>& addends,
const mpq_class& lb,
const mpq_class& ub)
override;
41 RowIndex AddRow(
const Expression::Addends& lhs,
FormulaKind sense,
const mpq_class& rhs)
override;
76 template <IsAnyOf<
double, mpq_
class> T>
77 LpResult InternalSolve(
const Matrix<T>& A,
const Vector<T>& b,
const Vector<T>& c,
const T& tolerance,
78 internal::Basis<T>& basis, Vector<T>* x =
nullptr, T* obj =
nullptr);
79 LpResult FeasibilitySolve(Matrix<mpq_class>& slack_A, Vector<mpq_class>& slack_b,
80 internal::Basis<mpq_class>& slack_basis);
81 LpResult OptimalitySolve(
const Matrix<mpq_class>& slack_A,
const Vector<mpq_class>& slack_b,
82 const Vector<mpq_class>& slack_c, internal::Basis<mpq_class>& slack_basis);
83 LpResult FeasibilityCheck(
const Matrix<mpq_class>& aux_A,
const Vector<mpq_class>& slack_b,
84 const Vector<mpq_class>& aux_c,
const internal::Basis<mpq_class>& feas_basis)
const;
85 LpResult OptimalityCheck(
const Matrix<mpq_class>& slack_A,
const Vector<mpq_class>& slack_b,
86 const Vector<mpq_class>& slack_c,
const internal::Basis<mpq_class>& basis);
87 LpResult UnboundednessCheck(
const Matrix<mpq_class>& slack_A,
const Vector<mpq_class>& slack_b,
88 const Vector<mpq_class>& slack_c,
const internal::Basis<mpq_class>& basis)
const;
99 void RemoveAuxiliaryColumns(
const internal::Basis<mpq_class>& feas_basis,
const std::vector<Index>& aux_columns,
100 Matrix<mpq_class>& slack_A, Vector<mpq_class>& slack_b,
101 internal::Basis<mpq_class>& slack_basis)
const;
129 void SlackForm(Matrix<mpq_class>& slack_A, Vector<mpq_class>& slack_c)
const;
142 internal::Basis<mpq_class>
AuxForm(
const Matrix<mpq_class>& slack_A,
const Vector<mpq_class>& slack_b,
143 Matrix<mpq_class>& aux_A, Vector<mpq_class>& aux_c,
144 std::vector<Index>& aux_columns)
const;
199 void UpdateInfeasible();
202 Vector<mpq_class>
x_;
207std::ostream& operator<<(std::ostream& os,
const DelpiLpSolver& solver);
Simple dataclass used to store the configuration of the program.
Linear programming solver using a custom implementation of the Simplex algorithm.
internal::LpProblem problem_
Linear programming problem.
void SetBound(Variable var, const mpq_class &lb, const mpq_class &ub) override
Set the bounds of a var in the LP problem to the given lb and ub.
void RemoveAuxiliaryColumns(const internal::Basis< mpq_class > &feas_basis, const std::vector< Index > &aux_columns, Matrix< mpq_class > &slack_A, Vector< mpq_class > &slack_b, internal::Basis< mpq_class > &slack_basis) const
Use aux_basis to update basis with a set of columns we know feasible.
LpResult InternalSolve(const Matrix< T > &A, const Vector< T > &b, const Vector< T > &c, const T &tolerance, internal::Basis< T > &basis, Vector< T > *x=nullptr, T *obj=nullptr)
Solve the LP problem using the Simplex algorithm.
Vector< mpq_class > x_
Solution vector.
void ComputeSlackAndAuxVariables()
Compute the slack and auxiliary variables for the original LP problem stored in A_,...
void ReserveRows(int num_rows) override
Reserve space for the given number of rows.
void EnsureSenseCore() override
Make sure the LP solvers are aware of the sense of the LP problem (minimisation or maximisation).
LpResult SolveCore() override
Internal method that optimises the LP problem with the given delta.
void ReserveColumns(int num_columns) override
Reserve space for the given number of columns and rows.
Row row(RowIndex row_idx) const override
Get the row at the given row_idx index.
Column column(ColumnIndex column_idx) const override
Get the column at the given column_idx index.
void SlackForm(Matrix< mpq_class > &slack_A, Vector< mpq_class > &slack_c) const
Convert a generic LP problem into the standard form by adding slack variables where needed.
mpq_class delta_
Precision for the optimality check.
internal::Basis< mpq_class > AuxForm(const Matrix< mpq_class > &slack_A, const Vector< mpq_class > &slack_b, Matrix< mpq_class > &aux_A, Vector< mpq_class > &aux_c, std::vector< Index > &aux_columns) const
Convert a standard form LP problem into a feasible and bounded auxiliary problem.
ColumnIndex AddColumn(const Variable &var, const mpq_class &obj, const mpq_class &lb, const mpq_class &ub) override
Add a new bounded column to the LP problem, ensuring that the variable var is in the range and has t...
void SetObjective(int column, const mpq_class &value) override
The the objective coefficient of the given column to the given value.
void SetCoefficient(RowIndex row, ColumnIndex column, const mpq_class &value) override
Set the coefficient of the row constraint to apply at the column decisional variable.
const Variable & var(const int column) const
Shorthand notation to get the real variable linked with column column.
LpSolver(mpq_class ninfinity, mpq_class infinity, Config config={}, const std::string &class_name="LpSolver")
Construct a new LpSolver object with the given config.
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.
Structure representing a row in the LP solver in the form of a linear combination of variables.