22 #include <lpsolve/lp_lib.h>
27 void throwExceptionIfError(
const unsigned char& status,
string errorMsg);
28 void generateProblem(
const ILPModel& m, lprec* ilp);
31 string identification =
"LPSolve";
32 int major = -1, minor = -1, release = -1, build = -1;
33 lp_solve_version(&major, &minor, &release, &build);
34 if (major != -1 && minor != -1 && release != -1 && build != -1)
35 identification +=
" "+to_string(major)+
"."+to_string(minor)+
"."+to_string(release)+
"."+to_string(build);
36 return identification;
42 lprec *model =
nullptr;
45 model = make_lp(m.numberOfConstraints(), m.numberOfVariables());
49 generateProblem(m, model);
52 set_verbose(model, NEUTRAL);
54 set_mip_gap(model, FALSE, gap);
56 set_timeout(model, static_cast<long>(ceil(timeLimit)));
58 set_presolve(model, PRESOLVE_ROWS | PRESOLVE_BOUNDS, get_presolveloops(model));
59 switch (solve(model)) {
76 if (s.
status == ILP_OPTIMAL || s.
status == ILP_FEASIBLE) {
77 double *vars =
nullptr;
78 get_ptr_variables(model, &vars);
79 if (vars !=
nullptr) {
81 for (
unsigned long v = 0; v < m.numberOfVariables(); ++v)
89 if (s.
status == ILP_OPTIMAL) {
93 for (
unsigned long v = 0; v < m.numberOfVariables(); ++v) {
94 if (m.
obj == MINIMIZE && m.
c[v] > 0.0)
95 s.
bound += m.
c[v]*m.
x[v].lowerBound;
96 else if (m.
obj == MINIMIZE && m.
c[v] < 0.0)
97 s.
bound += m.
c[v]*m.
x[v].upperBound;
98 else if (m.
obj == MAXIMIZE && m.
c[v] > 0.0)
99 s.
bound += m.
c[v]*m.
x[v].upperBound;
100 else if (m.
obj == MAXIMIZE && m.
c[v] < 0.0)
101 s.
bound += m.
c[v]*m.
x[v].lowerBound;
109 throw_with_nested(
ILPSolverException(caller(),
"Error during solving the ILP problem!"));
115 void throwExceptionIfError(
const unsigned char& status,
string errorMsg) {
120 void generateProblem(
const ILPModel& m, lprec* ilp) {
122 if (m.
obj == MINIMIZE)
127 vector<double> crit(1, 0.0);
128 crit.insert(crit.end(), m.
c.cbegin(), m.
c.cend());
129 throwExceptionIfError(set_obj_fn(ilp, crit.data()),
"LPSolve - cannot set the objective function!");
131 for (
unsigned long v = 0; v < m.numberOfVariables(); ++v) {
132 if (m.
x[v].type == BIN || m.
x[v].type == INT)
133 throwExceptionIfError(set_int(ilp, v+1, TRUE),
"LPSolve - cannot set the integer type of the variable!");
135 throwExceptionIfError(set_bounds(ilp, v+1, m.
x[v].lowerBound, m.
x[v].upperBound),
"LPSolve - cannot set variable bounds!");
136 throwExceptionIfError(set_col_name(ilp, v+1, (
char*) m.
varDesc[v].c_str()),
"LPSolve - cannot set the variable name!");
139 throwExceptionIfError(set_add_rowmode(ilp, TRUE),
"LPSolve - 'rowmode' should be changed!");
140 for (
unsigned long c = 0; c < m.numberOfConstraints(); ++c) {
142 vector<double> conCoeff;
143 for (
const pair<uint32_t, double>& p : m.
A[c]) {
144 conIdx.push_back(p.first+1);
145 conCoeff.push_back(p.second);
150 throwExceptionIfError(add_constraintex(ilp, conIdx.size(), conCoeff.data(), conIdx.data(), LE, m.
b[c]),
"LPSolve - cannot add the constraint!");
153 throwExceptionIfError(add_constraintex(ilp, conIdx.size(), conCoeff.data(), conIdx.data(), EQ, m.
b[c]),
"LPSolve - cannot add the constraint!");
156 throwExceptionIfError(add_constraintex(ilp, conIdx.size(), conCoeff.data(), conIdx.data(), GE, m.
b[c]),
"LPSolve - cannot add the constraint!");
159 throwExceptionIfError(set_row_name(ilp, c+1, (
char*) m.
conDesc[c].c_str()),
"LPSolve - cannot set the constraint name!");
161 throwExceptionIfError(set_add_rowmode(ilp, FALSE),
"LPSolve - 'rowmode' should be turned off!");
std::vector< double > b
Constants in the constraints, i.e. the right-hand side vector of .
SparseMatrix< double > A
Constraint matrix of the problem.
Integer Linear Programming problem is stored in this data structure.
std::vector< double > solution
The best found solution.
Structure storing a solution of an Integer Linear Programming problem.
std::vector< std::string > varDesc
Optional description of the variables.
Solver-independent interface for solving Integer Linear Programming problems.
Exception dedicated to problems with Integer Linear Programming solvers.
double criterion
The criterion value of the solution.
std::vector< Operator > ops
Operators of the constraints, see Operator enum.
std::string solverIdentification()
Returns an identification of the used solver, e.g. 'Gurobi 6.0.4'.
double bound
The best known lower or upper bound.
std::vector< double > c
Vector of the criterion coefficients.
Objective obj
Sense of the objective function (minimization/maximization).
Status status
Solution status, see Status enum.
std::vector< Variable > x
Variables of the problem.
SolutionILP solveILP(const ILPModel &m, bool verbose, double gap=0.0, double timeLimit=0.0, int numberOfThreads=1, int threadId=0)
Integer Linear Programming solver is called to solve the problem and the solution is returned...
std::vector< std::string > conDesc
Optional description of the constraints.