solver  1.0
CplexSolver.cpp
1 /*
2  This file is part of the EnergyOptimizatorOfRoboticCells program.
3 
4  EnergyOptimizatorOfRoboticCells is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  EnergyOptimizatorOfRoboticCells is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with EnergyOptimizatorOfRoboticCells. If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include <string>
19 #include <stdexcept>
20 #include <vector>
21 #include <ilcplex/ilocplex.h>
23 
24 using namespace std;
25 
26 ILOSTLBEGIN
27 
28 void generateProblem(const ILPModel& m, IloModel& model, IloNumVarArray& x, IloRangeArray& con);
29 
31  IloEnv env;
32  IloCplex cplex(env);
33  string identification = "Cplex "+string(cplex.getVersion());
34  env.end();
35 
36  return identification;
37 }
38 
39 SolutionILP solveILP(const ILPModel& m, bool verbose, double gap, double timeLimit, int numberOfThreads, int) {
40 
41  IloEnv env;
42  SolutionILP solution;
43 
44  try {
45  IloModel model(env);
46  IloObjective obj(env);
47  IloNumVarArray var(env);
48  IloRangeArray con(env);
49  generateProblem(m, model, var, con);
50 
51  IloCplex cplex(model);
52  cplex.setParam(IloCplex::Threads, numberOfThreads);
53  if (!verbose)
54  cplex.setOut(env.getNullStream());
55  if (gap != 0.0)
56  cplex.setParam(IloCplex::EpGap, gap);
57  if (timeLimit != 0.0)
58  cplex.setParam(IloCplex::TiLim, timeLimit);
59 
60  cplex.solve();
61  switch (cplex.getStatus()) {
62  case IloAlgorithm::Optimal:
63  solution.status = ILP_OPTIMAL;
64  break;
65  case IloAlgorithm::Feasible:
66  solution.status = ILP_FEASIBLE;
67  break;
68  case IloAlgorithm::Infeasible:
69  solution.status = ILP_INFEASIBLE;
70  break;
71  case IloAlgorithm::Unbounded:
72  solution.status = ILP_UNBOUNDED;
73  break;
74  default:
75  solution.status = ILP_UNKNOWN;
76  }
77 
78  if (solution.status == ILP_OPTIMAL || solution.status == ILP_FEASIBLE) {
79  IloNumArray sol(env);
80  cplex.getValues(sol, var);
81  solution.criterion = cplex.getObjValue();
82  for (long v = 0; v < sol.getSize(); ++v)
83  solution.solution.push_back(sol[v]);
84  }
85 
86  solution.bound = cplex.getBestObjValue(); // Can throw IloException!
87  env.end();
88 
89  } catch (IloException& e) {
90  env.end();
91  throw ILPSolverException(caller(), e.getMessage());
92  } catch (...) {
93  env.end();
94  throw_with_nested(ILPSolverException(caller(), "Error during solving the ILP problem!"));
95  }
96 
97  return solution;
98 }
99 
100 void generateProblem(const ILPModel& m, IloModel& model, IloNumVarArray& x, IloRangeArray& con) {
101  IloEnv env = model.getEnv();
102  IloObjective obj = (m.obj == MINIMIZE ? IloMinimize(env) : IloMaximize(env));
103  for (unsigned long v = 0; v < m.numberOfVariables(); ++v) {
104  switch (m.x[v].type) {
105  case FLT:
106  x.add(IloNumVar(env, m.x[v].lowerBound, m.x[v].upperBound, IloNumVar::Float));
107  break;
108  case BIN:
109  x.add(IloNumVar(env, m.x[v].lowerBound, m.x[v].upperBound, IloNumVar::Bool));
110  break;
111  default:
112  x.add(IloNumVar(env, m.x[v].lowerBound, m.x[v].upperBound, IloNumVar::Int));
113  }
114 
115  obj.setLinearCoef(x[v], m.c[v]);
116  x[v].setName(m.varDesc[v].c_str());
117  }
118 
119  for (unsigned long c = 0; c < m.numberOfConstraints(); ++c) {
120  switch (m.ops[c]) {
121  case LESS_EQUAL:
122  con.add(IloRange(env, -IloInfinity, m.b[c]));
123  break;
124  case EQUAL:
125  con.add(IloRange(env, m.b[c], m.b[c]));
126  break;
127  case GREATER_EQUAL:
128  con.add(IloRange(env, m.b[c], IloInfinity));
129  }
130 
131  for (const pair<uint32_t, double>& p : m.A[c])
132  con[c].setLinearCoef(x[p.first], p.second);
133 
134  con[c].setName(m.conDesc[c].c_str());
135  }
136 
137  model.add(obj);
138  model.add(con);
139 }
140 
std::vector< double > b
Constants in the constraints, i.e. the right-hand side vector of .
Definition: ILPModel.h:87
SparseMatrix< double > A
Constraint matrix of the problem.
Definition: ILPModel.h:81
STL namespace.
Integer Linear Programming problem is stored in this data structure.
Definition: ILPModel.h:69
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.
Definition: ILPModel.h:93
Solver-independent interface for solving Integer Linear Programming problems.
Exception dedicated to problems with Integer Linear Programming solvers.
Definition: Exceptions.h:127
double criterion
The criterion value of the solution.
std::vector< Operator > ops
Operators of the constraints, see Operator enum.
Definition: ILPModel.h:89
std::string solverIdentification()
Returns an identification of the used solver, e.g. 'Gurobi 6.0.4'.
Definition: CplexSolver.cpp:30
double bound
The best known lower or upper bound.
std::vector< double > c
Vector of the criterion coefficients.
Definition: ILPModel.h:83
Objective obj
Sense of the objective function (minimization/maximization).
Definition: ILPModel.h:79
Status status
Solution status, see Status enum.
std::vector< Variable > x
Variables of the problem.
Definition: ILPModel.h:91
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...
Definition: CplexSolver.cpp:39
std::vector< std::string > conDesc
Optional description of the constraints.
Definition: ILPModel.h:95