solver  1.0
RoboticLineSolverILP.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 <algorithm>
19 #include <cmath>
20 #include <chrono>
21 #include <map>
22 #include <set>
23 #include <string>
24 #include "Settings.h"
25 #include "SolverConfig.h"
26 #include "Shared/Utils.h"
27 #include "Shared/Exceptions.h"
30 
31 using namespace std;
32 using namespace std::chrono;
33 
35  ConstraintsGenerator generator(r, &m);
36  construct(generator, false);
37 }
38 
40  ConstraintsGenerator generator(l, &m);
41  construct(generator, l.robots().size() > 1);
42 }
43 
44 Solution RoboticLineSolverILP::solve(double relGap, double timLim) const {
45 
46  #ifdef GUROBI_SOLVER
48  #endif
49 
50  Solution s;
51  high_resolution_clock::time_point start = high_resolution_clock::now();
53  s.runTime = duration_cast<duration<double>>(high_resolution_clock::now()-start).count();
54  s.status = convert(sILP.status);
55 
56  if (sILP.status == ILP_OPTIMAL || sILP.status == ILP_FEASIBLE) {
57 
58  s.lowerBound = sILP.bound;
59  s.totalEnergy = sILP.criterion;
60 
61  try {
62  set<uint32_t> selectedActivities;
63  map<uint32_t, double> idToStart = inverseMapping(sILP.solution, mMapper.s);
64  map<uint32_t, double> idToDuration = inverseMapping(sILP.solution, mMapper.d);
65  map<uint32_t, uint32_t> idToPoint = inverseMapping(sILP.solution, mMapper.x);
66  map<uint32_t, uint32_t> idToPowerMode = inverseMapping(sILP.solution, mMapper.z);
67  map<uint32_t, uint32_t> idToMovement = inverseMapping(sILP.solution, mMapper.y);
68 
69  if (idToStart.size() != idToDuration.size() && idToPoint.size() != idToPowerMode.size())
70  throw SolverException(caller(), "ILP model is invalid probably!");
71 
72  double minStartTime = F64_MAX;
73  for (const auto& p : idToPoint) {
74  uint32_t aid = p.first, point = p.second;
75  uint32_t pwrm = getValue(idToPowerMode, aid, caller());
76  setValue(s.pointAndPowerMode, aid, {point, pwrm}, caller());
77  minStartTime = min(minStartTime, getValue(idToStart, aid, caller()));
78  selectedActivities.insert(aid);
79  }
80 
81  for (const auto& p : idToMovement) {
82  minStartTime = min(minStartTime, getValue(idToStart, p.first, caller()));
83  selectedActivities.insert(p.first);
84  }
85 
86  for (const uint32_t& aid : selectedActivities) {
87  double start = getValue(idToStart, aid, caller())-minStartTime; // Set initial time of Gantt chart to zero.
88  double duration = getValue(idToDuration, aid, caller());
89  setValue(s.startTimeAndDuration, aid, {start, duration}, caller());
90  }
91  } catch (...) {
92  throw_with_nested(SolverException(caller(), "Cannot map ILP solution to the problem solution!\nCheck validity of the model..."));
93  }
94 
95  } else if (sILP.status != ILP_UNKNOWN) {
96  s.lowerBound = sILP.bound;
97  }
98 
99  return s;
100 }
101 
102 double RoboticLineSolverILP::lowerBoundOnEnergy(const vector<Robot*>& robots, const PrecalculatedMapping& m) {
103  double lowerBound = 0.0;
104  for (Robot* r : robots) {
105  RoboticLineSolverILP solver(r, m);
106  Solution s = solver.solve(0.0, Settings::RUNTIME_OF_LOWER_BOUND/robots.size());
107  lowerBound += s.lowerBound;
108  }
109 
110  return lowerBound;
111 }
112 
113 void RoboticLineSolverILP::construct(ConstraintsGenerator& generator, bool addGlobalConstraints) {
114 
115  try {
118  generator.addFlowConstraints(mMapper.x, mMapper.y);
121  if (addGlobalConstraints)
123 
124  mModel.c.resize(mMapper.numberOfVariables(), 0.0);
125  for (const auto& p : mMapper.W)
126  mModel.c[p.second] = 1.0;
127 
128  } catch (...) {
129  string msg = "Cannot add constraints to the ILP model!\nEither variable mapping or RoboticLine data-structure is corrupted!";
130  throw_with_nested(SolverException(caller(), msg));
131  }
132 
133  mModel.x = move(mMapper.variables);
134  mModel.varDesc = move(mMapper.varDesc);
135  generator.moveConstraintsToModel(mModel);
136  #ifndef NDEBUG
138  #endif
139 
140  if (Settings::VERBOSE == true) {
141  cout<<endl;
143  cout<<endl;
144  }
145 }
146 
void initializeLocalEnvironments(int numberOfThreads)
It enables the solver to initialize all the data structures (e.g. expensive to construct) required fo...
void printStatistics() const
It prints various statistics like density of A matrix and number of constraints to the standard outpu...
Definition: ILPModel.cpp:46
double totalEnergy
The amount of energy required per robot cycle.
Definition: Solution.h:57
Generation of the (I)LP constraints.
The structure representing a solution found by an algorithm.
Definition: Solution.h:50
Instance of this class includes all the data structures and methods related to a robot.
Definition: RoboticLine.h:432
std::vector< Variable > variables
Continuous variables of the problem with the well-specified domains.
uint32_t numberOfVariables() const
Total number of variables including both continuous and binary ones.
map4toN c
Binary variables used for collisions resolution.
RoboticLineSolverILP(Robot *r, const PrecalculatedMapping &m)
Integer Linear Programming problem is built from the robot.
VariableMappingILP mMapper
Mapping of both the continuous and binary variables.
double runTime
Run time (seconds) of the optimization algorithm required for obtaining this solution.
Definition: Solution.h:61
void addUniqueModeSelection(const map2to1 &x, map2to1 &z)
It calls addUniquePointSelection and addUniquePowerModeSelection methods.
State convert(const Status &ilpStatus)
Conversion between the ILP solver status and the solution state.
Definition: Solution.cpp:29
STL namespace.
A general exception of the program.
Definition: Exceptions.h:58
std::vector< std::string > varDesc
Description of the continuous variables.
double RUNTIME_OF_LOWER_BOUND
Time limit for the tight lower bound.
Definition: Settings.cpp:39
Solution solve(double relGap=Settings::ILP_RELATIVE_GAP, double timLim=Settings::MAX_RUNTIME) const
ILP solver optimizes the energy consumption of the robotic cell until a stop criterion is reached...
std::vector< double > solution
The best found solution.
Various auxiliary functions used across the program.
bool VERBOSE
Boolean flag determining verbosity of the program.
Definition: Settings.cpp:28
Structure storing a solution of an Integer Linear Programming problem.
uint32_t NUMBER_OF_THREADS
Maximal number of threads to be used.
Definition: Settings.cpp:30
void addEnergyFunctions(const map1to1 &d, const map1to1 &W, const map2to1 &x, const map2to1 &z, const map2to1 &y)
It adds the energy functions of both the static and dynamic activities.
The file defines extended exceptions for the better error handling in the program.
std::vector< std::string > varDesc
Optional description of the variables.
Definition: ILPModel.h:93
An exact solver for the energy optimization problem.
std::map< uint32_t, std::pair< uint32_t, uint32_t > > pointAndPowerMode
It maps the identification of a static activity to its assigned coordinate and used power saving mode...
Definition: Solution.h:67
Solver-independent interface for solving Integer Linear Programming problems.
map1to1 s
Maps activity identification to the index of variable corresponding to the start time of this activit...
State status
Enum specifying whether the solution is optimal, feasible, or infeasible...
Definition: Solution.h:55
double criterion
The criterion value of the solution.
void addFlowConstraints(const map2to1 &x, const map2to1 &y)
Add flow preservation constraints ensuring that robot leaves the same location as it enters...
static double lowerBoundOnEnergy(const std::vector< Robot * > &robots, const PrecalculatedMapping &m)
A tight lower bound on the energy consumption.
double bound
The best known lower or upper bound.
It declares the namespace for program settings.
std::map< uint32_t, uint32_t > inverseMapping(const std::vector< double > &solution, const map2to1 &mapping)
It extracts the variables set to true and returns the ,,selected" indices.
void construct(ConstraintsGenerator &generator, bool addGlobalConstraints=true)
It builds the Integer Linear Programming problem corresponding to the energy optimization problem of ...
std::vector< double > c
Vector of the criterion coefficients.
Definition: ILPModel.h:83
void addAllPrecedences(const map1to1 &s, const map1to1 &d, const map2to1 &y, const map2to1 &w)
It calls all the methods related to the order of activities.
map1to1 W
Maps activity identification to the index of variable corresponding to the energy consumption of this...
void addGlobalConstraints(const map1to1 &s, const map1to1 &d, const map2to1 &x, const map2to1 &y, const map4toN &c)
Adds all the global constraints, i.e. time lags, spatial compatibility, and collision resolution...
map1to1 d
Maps activity identification to the index of variable corresponding to the duration of this activity...
Status status
Solution status, see Status enum.
std::vector< Variable > x
Variables of the problem.
Definition: ILPModel.h:91
void addDurationConstraints(const map1to1 &d, const map2to1 &z, const map2to1 &y)
It constructs all the constraints that limit the duration of activities.
double lowerBound
Lower bound on energy, i.e. there is not a solution consuming less energy than this number...
Definition: Solution.h:59
ILPModel mModel
The energy optimization of the robotic cell formulated as an Integer Linear Programming 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...
Definition: CplexSolver.cpp:39
void checkFormulation() const
It checks that sizes of vectors and the matrix are valid.
Definition: ILPModel.cpp:27
The robotic cell corresponds to an instance of this class.
Definition: RoboticLine.h:563
The structure contains the maps for fast searching in the robotic cell.
RoboticLineSolverILP class, declared in this file, addresses the energy optimization problem of robot...
uint64_t moveConstraintsToModel(ILPModel &m)
It efficiently moves all the generated constraints to the given model.
std::map< uint32_t, std::pair< double, double > > startTimeAndDuration
Mapping of the activity identification to its start time and duration.
Definition: Solution.h:65