solver  1.0
Solution.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 <fstream>
19 #include <string>
20 #include <vector>
21 #include "SolverConfig.h"
22 #include "Solution/Solution.h"
23 #include "Shared/Exceptions.h"
25 #include "Shared/Utils.h"
26 
27 using namespace std;
28 
29 State convert(const Status& ilpStatus) {
30  State solStatus;
31  switch (ilpStatus) {
32  case ILP_OPTIMAL:
33  solStatus = OPTIMAL;
34  break;
35  case ILP_FEASIBLE:
36  solStatus = FEASIBLE;
37  break;
38  case ILP_INFEASIBLE:
39  solStatus = INFEASIBLE;
40  break;
41  default:
42  solStatus = UNKNOWN;
43  }
44 
45  return solStatus;
46 }
47 
48 ostream& operator<<(ostream& out, const Solution& s) {
49  vector<string> toPrint;
50  if (s.status == OPTIMAL || s.status == FEASIBLE) {
51  toPrint.emplace_back("Solution is "+string(s.status == OPTIMAL ? "optimal" : "feasible")+".");
52  toPrint.emplace_back("Total energy consumed: "+to_string(s.totalEnergy)+" J");
53  if (s.lowerBound > 0.0)
54  toPrint.emplace_back("Lower bound on energy: "+to_string(s.lowerBound)+" J\n");
55  else
56  toPrint.emplace_back("");
57 
58  for (const auto& mit : s.startTimeAndDuration) {
59  string line = "activity "+to_string(mit.first)+": ";
60  line += to_string(mit.second.first)+"+"+to_string(mit.second.second);
61  const auto& sit = s.pointAndPowerMode.find(mit.first);
62  if (sit != s.pointAndPowerMode.cend())
63  line += " (point="+to_string(sit->second.first)+", mode="+to_string(sit->second.second)+")";
64  toPrint.push_back(move(line));
65  }
66 
67  if (s.runTime >= 0.0 || s.memUsage >= 0.0) {
68  toPrint.push_back("");
69  if (s.runTime >= 0.0)
70  toPrint.push_back("Run time: "+to_string(s.runTime)+" s");
71  if (s.memUsage >= 0.0)
72  toPrint.push_back("Memory usage: "+to_string(s.memUsage)+" Bytes");
73  }
74  } else {
75  if (s.status == INFEASIBLE)
76  toPrint.push_back("No feasible solution exists!");
77  else
78  toPrint.push_back("Solution not found!");
79  }
80 
81  for (uint64_t l = 0; l < toPrint.size(); ++l) {
82  if (l+1 < toPrint.size())
83  out<<toPrint[l]<<endl;
84  else
85  out<<toPrint[l];
86  }
87 
88  return out;
89 }
90 
91 ostream& operator<<(ostream& out, const State& st) {
92  switch (st) {
93  case OPTIMAL:
94  out<<"optimal";
95  break;
96  case FEASIBLE:
97  out<<"feasible";
98  break;
99  case INFEASIBLE:
100  out<<"infeasible";
101  break;
102  default:
103  out<<"unknown";
104  }
105 
106  return out;
107 }
108 
109 void writeSolutionToCsvFile(const string& file, const Solution& s, const PrecalculatedMapping& mapper) {
110  ofstream out(file.c_str(), ofstream::out | ofstream::trunc);
111  if (!out)
112  throw SolverException(caller(), "Cannot write to "+file+" file! Please check permissions.");
113 
114  if (s.status == OPTIMAL || s.status == FEASIBLE) {
115  out<<"activity id, start time, duration, type, point, power saving mode, movement, energy"<<endl;
116  for (const auto& mit : s.startTimeAndDuration) {
117  uint32_t aid = mit.first;
118  Activity* a = getValue(mapper.aidToActivity, aid, caller());
119  double start = mit.second.first, duration = mit.second.second;
120 
121  out<<aid<<", "<<start<<", "<<duration<<", ";
122 
123  StaticActivity* sa = dynamic_cast<StaticActivity*>(a);
124  if (sa != nullptr) {
125  Location *loc = nullptr;
126  uint32_t point, powerMode;
127  try {
128  const auto p = getValue(s.pointAndPowerMode, aid, caller());
129  point = p.first; powerMode = p.second;
130  loc = getValue(mapper.pointToLocation, point, caller());
131  } catch (...) {
132  string msg = "Incomplete solution - cannot find selected point and power saving mode for activity "+to_string(aid)+"!";
133  throw_with_nested(SolverException(caller(), msg));
134  }
135 
136  out<<"STATIC, "<<point<<", "<<powerMode<<", NA, "<<sa->energyConsumption(duration, loc->lid(), powerMode)<<endl;
137  }
138 
139  DynamicActivity* da = dynamic_cast<DynamicActivity*>(a);
140  if (da != nullptr) {
141  Movement *mv = getSelectedMovement(s, mapper, da);
142  out<<"DYNAMIC, NA, NA, "<<mv->mid()<<", "<<mv->energyConsumption(duration)<<endl;
143  }
144  }
145  } else {
146  out<<(s.status == INFEASIBLE ? "No feasible solution exists!" : "Solution not found!")<<endl;
147  }
148 
149  out.close();
150 }
151 
152 void writeBriefResultToStream(std::ostream& OUT, const string& instanceName, const Solution& s) {
153  OUT<<instanceName<<" ("<<s.status<<", "<<s.runTime<<" s): ";
154  if (s.status == FEASIBLE || s.status == OPTIMAL) {
155  if (s.lowerBound > 0.0)
156  OUT<<"from "<<s.lowerBound<<" to "<<s.totalEnergy<<endl;
157  else
158  OUT<<s.totalEnergy<<endl;
159  } else {
160  OUT<<"?"<<endl;
161  }
162 }
163 
164 void writeBriefResultToCsvFile(const std::string& instanceName, const std::string& pathToFile, const Solution& s) {
165  bool writeHeader = !fileExists(pathToFile);
166  ofstream resFile(pathToFile.c_str(), ofstream::app);
167  if (resFile.good()) {
168  if (writeHeader)
169  resFile<<"instance name, status, lower bound on energy, total energy, runtime [s]"<<endl;
170 
171  resFile<<instanceName<<", "<<s.status<<", ";
172  if (s.status == FEASIBLE || s.status == OPTIMAL)
173  resFile<<s.lowerBound<<", "<<s.totalEnergy<<", ";
174  else
175  resFile<<"NA, NA, ";
176 
177  resFile<<s.runTime<<endl;
178  } else {
179  cerr<<"Warning: Cannot open '"<<pathToFile<<"' file for writing of results!"<<endl;
180  }
181 
182  resFile.close();
183 }
184 
The instance of the class corresponds to a robot movement between two coordinates.
Definition: RoboticLine.h:133
double totalEnergy
The amount of energy required per robot cycle.
Definition: Solution.h:57
The base class incorporating common properties of robot operations and movements. ...
Definition: RoboticLine.h:68
The structure representing a solution found by an algorithm.
Definition: Solution.h:50
Collection of movements between two static activities.
Definition: RoboticLine.h:261
double runTime
Run time (seconds) of the optimization algorithm required for obtaining this solution.
Definition: Solution.h:61
std::map< uint32_t, Location * > pointToLocation
Unique coordinate, i.e. a point, to the related location.
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
The structures and methods suitable for fast searching in the data structure of the robotic cell...
bool fileExists(const std::string &pathToFile)
It checks the existence of the file.
Definition: Utils.cpp:85
ostream & operator<<(ostream &out, const Solution &s)
It prints the solution to the output stream.
Definition: Solution.cpp:48
Various auxiliary functions used across the program.
The file defines extended exceptions for the better error handling in the program.
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
Collection of locations in which a robot operation (or waiting) can be performed. ...
Definition: RoboticLine.h:304
State status
Enum specifying whether the solution is optimal, feasible, or infeasible...
Definition: Solution.h:55
void writeBriefResultToCsvFile(const std::string &instanceName, const std::string &pathToFile, const Solution &s)
It writes the solution to the file in the same format as writeBriefResultToStream function...
Definition: Solution.cpp:164
Status
Constants specifying whether a solution is optimal, feasible, infeasible, unbounded, or undefined, respectively.
double memUsage
Memory usage (bytes) of the optimization algorithm, currently not used due to implementation issues...
Definition: Solution.h:63
double energyConsumption(double duration, const uint32_t &lid, const uint32_t &pid) const
Movement * getSelectedMovement(const Solution &s, const PrecalculatedMapping &m, DynamicActivity *da)
It extracts the selected movement of the given dynamic activity from the solution.
void writeSolutionToCsvFile(const string &file, const Solution &s, const PrecalculatedMapping &mapper)
It writes the solution to a csv file, the header is 'activity id, start time, duration, type, point, power saving mode, movement, energy'.
Definition: Solution.cpp:109
State
Enum declares constants specifying whether a found solution is optimal, feasible, infeasible...
Definition: Solution.h:38
double energyConsumption(const double &duration) const
Definition: RoboticLine.cpp:31
A representation of the solution that is algorithm independent.
double lowerBound
Lower bound on energy, i.e. there is not a solution consuming less energy than this number...
Definition: Solution.h:59
void writeBriefResultToStream(std::ostream &OUT, const string &instanceName, const Solution &s)
It prints the solution as follows: 'instance name (state, runtime s): energy'.
Definition: Solution.cpp:152
Location of the robot used either during work (welding) or waiting.
Definition: RoboticLine.h:192
The structure contains the maps for fast searching in the robotic cell.
std::map< uint32_t, Activity * > aidToActivity
Activity identification to its pointer.
std::map< uint32_t, std::pair< double, double > > startTimeAndDuration
Mapping of the activity identification to its start time and duration.
Definition: Solution.h:65