solver  1.0
KnowledgeBase.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 "Settings.h"
20 
21 using namespace std;
22 
23 KnowledgeBase::KnowledgeBase() : mAddedTuples(0u), mProcessedTuples(0u), mOptimizationPhaseCounter(0u), mInfDueToLP(0u),
24  mInfDueToLocHeur(0u), mInfDueToPwrmHeur(0u), mInfDueToChangedPath(0u), mInfeasibleCounter(0u), mLPCalls(0u), mLPFixCalls(0u),
25  mPartProbCalls(0u), mLocHeurCalls(0u), mPwrmHeurCalls(0u), mPathChangeCalls(0u), mSumOfIters(0u), mLPTime(0.0), mLocHeurTime(0.0),
26  mPwrmHeurTime(0.0), mTupleGenTime(0.0), mSumOfDeteriorations(0u), mSumOfLocHeurErrs(0.0), mSumOfPwrmHeurErrs(0.0) { }
27 
28 list<pair<Solution, CircuitTuple>> KnowledgeBase::eliteSolutions() {
29  mEliteMtx.lock();
30  list<pair<Solution, CircuitTuple>> sols = mEliteSolutions;
31  mEliteMtx.unlock();
32  return sols;
33 }
34 
36  Solution best;
37  if (!mEliteSolutions.empty())
38  best = mEliteSolutions.front().first;
39  else
40  throw EmptySolutionPool(caller(), "No feasible solution found!");
41 
42  return best;
43 }
44 
46 
47  if (s.status == INFEASIBLE || s.status == UNKNOWN)
48  return;
49 
50  mEliteMtx.lock();
51 
52  if (!mEliteSolutions.empty()) {
53  if (s.totalEnergy >= mEliteSolutions.back().first.totalEnergy) {
55  mEliteSolutions.push_back({s, t});
56  } else {
57  list<pair<Solution, CircuitTuple>>::iterator it = mEliteSolutions.begin(), eit = mEliteSolutions.end();
58  while (it != eit && it->first.totalEnergy <= s.totalEnergy) {
59  ++it;
60  }
61  mEliteSolutions.insert(it, {s, t});
63  mEliteSolutions.pop_back();
64  }
65  } else {
66  mEliteSolutions.push_back({s, t});
67  }
68 
69  mEliteMtx.unlock();
70 }
71 
73  mTuplesMtx.lock();
74  mTuples.push(move(t));
75  mTuplesMtx.unlock();
76  ++mAddedTuples;
77 }
78 
80  CircuitTuple tuple;
81  mTuplesMtx.lock();
82  if (!mTuples.empty()) {
83  tuple = mTuples.front(); mTuples.pop();
84  mTuplesMtx.unlock();
85  } else {
86  mTuplesMtx.unlock();
87  throw EmptySolutionPool(caller(), "No tuples are ready to be processed!");
88  }
89 
91 
92  return tuple;
93 }
94 
95 void KnowledgeBase::addErrorMessage(const string& msg) {
96  mErrorsMtx.lock();
97  mErrorMessages.push_back(msg);
98  mErrorsMtx.unlock();
99 }
100 
103 }
104 
106  uint64_t calls = mLPCalls, infResults = mInfeasibleCounter;
107  if (calls > 0)
108  return (((double) infResults)/((double) calls));
109  else
110  return 0.0;
111 }
112 
113 void KnowledgeBase::recordLPCall(double runtime) {
114  record(runtime, mLPTime, mLPCalls);
115 }
116 
117 pair<uint64_t, double> KnowledgeBase::infoLP() {
118  return getInfo(mLPTime, mLPCalls);
119 }
120 
121 void KnowledgeBase::recordLPFixDeterioration(double deterioration) {
122  record(deterioration, mSumOfDeteriorations, mLPFixCalls);
123 }
124 
126  return getInfo(mSumOfDeteriorations, mLPFixCalls).second;
127 }
128 
130  uint64_t numOfLPCalls = mLPCalls, numOfLPFixCalls = mLPFixCalls;
131  if (mLPFixCalls > 0)
132  return (((double) numOfLPCalls)/((double) numOfLPFixCalls));
133  else
134  return 1.0;
135 }
136 
138  ++mPartProbCalls;
139 }
140 
141 void KnowledgeBase::recordLocHeurCall(double runtime) {
142  record(runtime, mLocHeurTime, mLocHeurCalls);
143 }
144 
145 pair<uint64_t, double> KnowledgeBase::infoLocHeur() {
147 }
148 
149 void KnowledgeBase::recordLocHeurRelErr(double relativeEstError) {
150  record(relativeEstError, mSumOfLocHeurErrs);
151 }
152 
154  return getInfo(mSumOfLocHeurErrs, mLocHeurCalls).second;
155 }
156 
157 void KnowledgeBase::recordPwrmHeurCall(double runtime) {
159 }
160 
161 pair<uint64_t, double> KnowledgeBase::infoPwrmHeur() {
163 }
164 
165 void KnowledgeBase::recordPwrmHeurRelErr(double relativeEstError) {
166  record(relativeEstError, mSumOfPwrmHeurErrs);
167 }
168 
170  return getInfo(mSumOfPwrmHeurErrs, mPwrmHeurCalls).second;
171 }
172 
174  record(runtime, mTupleGenTime);
175 }
176 
177 pair<uint64_t, double> KnowledgeBase::infoTuplesGeneration() {
179 }
180 
182  mSumOfIters += iters;
184 }
185 
186 pair<uint64_t, double> KnowledgeBase::infoItersPerTuple() {
187  uint64_t consideredTuples = mOptimizationPhaseCounter, sumOfIters = mSumOfIters;
188  if (consideredTuples > 0)
189  return {consideredTuples, ((double) sumOfIters)/((double) consideredTuples)};
190  else
191  return {0u, 0.0};
192 }
193 
195  uint64_t processed = mProcessedTuples, added = mAddedTuples;
196  if (added > 0)
197  return 100.0*(((double) processed)/((double) added));
198  else
199  return 100.0;
200 }
201 
202 template <class T>
203 extern void KnowledgeBase::record(T value, T& addTo) {
204  mStatMtx.lock();
205  addTo += value;
206  mStatMtx.unlock();
207 }
208 
209 template <class T>
210 extern void KnowledgeBase::record(T value, T& addTo, std::atomic<uint64_t>& counter) {
211  record(value, addTo);
212  ++counter;
213 }
214 
215 pair<uint64_t, double> KnowledgeBase::getInfo(double& aggregatedValue, std::atomic<uint64_t>& counter) {
216  mStatMtx.lock();
217  double totalValue = aggregatedValue;
218  uint64_t numCalls = counter;
219  mStatMtx.unlock();
220  if (numCalls > 0)
221  return {numCalls, totalValue/numCalls};
222  else
223  return {numCalls, 0.0};
224 }
225 
double totalEnergy
The amount of energy required per robot cycle.
Definition: Solution.h:57
void addTuple(CircuitTuple &&t)
Add a tuple to the mutex protected queue of tuples.
double mTupleGenTime
Aggregated processor time required for the generation of all the tuples.
The structure representing a solution found by an algorithm.
Definition: Solution.h:50
double mPwrmHeurTime
Aggregated processor time of all the (de)select power mode sub-heuristic calls.
void record(T value, T &addTo)
It carries out "addTo += value" operation, however protected by a mutex.
void candidate(const Solution &s, const CircuitTuple &t)
If a found solution ranks among the top ones, it is added to the list of elite solutions.
std::list< std::pair< Solution, CircuitTuple > > mEliteSolutions
List of elite solutions.
CircuitTuple getTuple()
Returns a partially fixed solution called tuple.
std::list< std::pair< Solution, CircuitTuple > > eliteSolutions()
Returns a list of elite solutions and their tuples from which they have been calculated.
STL namespace.
std::atomic< uint64_t > mProcessedTuples
The number of processed tuples.
std::pair< uint64_t, double > infoLocHeur()
Returns the total number of HeuristicAlgorithms::heuristicLocationChanges calls and average runtime f...
double percentageOfProcessed()
Percentage of the processed tuples.
std::atomic< uint64_t > mAddedTuples
Total number of generated tuples.
std::atomic< uint64_t > mOptimizationPhaseCounter
Records the number of tuples coming to the optimization process of the heuristic. ...
double mSumOfLocHeurErrs
The sum of the relative estimation errors (calculated by the change locations sub-heuristic) of energ...
uint32_t MAX_ELITE_SOLUTIONS
The number of top solutions maintained by the heuristic.
Definition: Settings.cpp:42
std::vector< std::string > mErrorMessages
Vector containing error messages of worker threads (to throw an exception later). ...
void recordLPFixDeterioration(double deterioration)
Reports a relative deterioration in the solution quality caused by the resolution of collisions...
std::pair< uint64_t, double > infoLP()
Returns the total number of Linear Programming calls and its average runtime for one worker thread...
void recordInfeasibleLP()
Reports that the solution of the Linear Programming problem was infeasible (one call of LP)...
Solution bestSolution()
Returns the best found solution, throws an exception if not available.
std::atomic< uint64_t > mSumOfIters
The total number of optimization iterations.
std::atomic< uint64_t > mInfeasibleCounter
How many times a Linear Programming solver returned an infeasible solution.
void addErrorMessage(const std::string &msg)
Add an error message to the mutex protected vector of messages.
std::atomic< uint64_t > mPwrmHeurCalls
The number of (de)select power mode sub-heuristic calls.
A partially fixed problem, i.e. tuple.
std::mutex mStatMtx
Mutex ensuring the flawless float operations for multiple concurrent threads.
std::atomic< uint64_t > mLPFixCalls
How many times a partially fixed problem was successfully solved.
void recordPwrmHeurCall(double runtime)
Reports a real time (measured by a timer) required by HeuristicAlgorithms::heuristicPowerModeSelectio...
State status
Enum specifying whether the solution is optimal, feasible, or infeasible...
Definition: Solution.h:55
double mLocHeurTime
Aggregated processor time of all the change locations sub-heuristic calls.
void recordLPCall(double runtime)
Reports a real time (measured by a timer) required for solving a partially fixed problem by Linear Pr...
void recordLocHeurRelErr(double relativeEstError)
Reports a relative estimation error of the change locations sub-heuristic for an energy improvement...
void recordNumberOfItersPerTuple(uint64_t iters)
Reports the number of optimization iterations performed for a loaded tuple.
std::mutex mErrorsMtx
Mutex protecting the access to the vector of error messages.
std::atomic< uint64_t > mLocHeurCalls
The number of change locations sub-heuristic calls.
std::atomic< uint64_t > mLPCalls
The number of Linear Programming calls.
std::mutex mTuplesMtx
Mutex protecting the access to the queue that contains tuples.
std::pair< uint64_t, double > infoItersPerTuple()
Returns the total number of tuples used for optimization and the average number of optimization itera...
void recordPwrmHeurRelErr(double relativeEstError)
Reports a relative estimation error of the (de)select power mode sub-heuristic for an energy improvem...
It declares the namespace for program settings.
double averageErrOfLocHeur()
Returns an average estimation error of the change locations sub-heuristic.
std::pair< uint64_t, double > getInfo(double &aggregatedValue, std::atomic< uint64_t > &counter)
Auxiliary method used for the calculation of an average time of a call based on a counter value and t...
double averageNumberOfLPCallsForLPFix()
Returns an average number of added precedences required for collisions avoidance. ...
std::pair< uint64_t, double > infoPwrmHeur()
Returns the total number of HeuristicAlgorithms::heuristicPowerModeSelection calls and average runtim...
Declares the class storing the best found solutions, tuples, and information about the heuristic perf...
std::queue< CircuitTuple > mTuples
Queue with the generated tuples.
double mLPTime
Aggregated processor time of all the Linear Programming calls.
double mSumOfPwrmHeurErrs
The sum of the relative estimation errors (calculated by the (de)select power mode sub-heuristic) of ...
double averageErrOfPwrmHeur()
Returns an average estimation error of the (de)select power mode sub-heuristic.
std::atomic< uint64_t > mPartProbCalls
How many times a partially fixed problem was evaluated, i.e. the number of calls of HeuristicAlgorith...
void recordPartialProblemSolveCall()
Reports that HeuristicAlgorithms::solvePartialProblem method was called.
std::mutex mEliteMtx
Mutex protecting the access to the list of elite solutions.
double mSumOfDeteriorations
The sum of relative deteriorations of the energy consumption caused by the collision resolution...
double averageLPFixDeterioration()
Returns an average quality deterioration caused by the collisions resolution.
std::pair< uint64_t, double > infoTuplesGeneration()
Returns the total number of generated tuples and the average generation time for one worker thread...
void recordAddTuplesCall(double runtime)
Reports a real time (measured by a timer) required for ParallelHeuristicSolver::addRandomTuplesToKB c...
double infeasibilityRate()
Infeasibility rate of Linear Programming, i.e. the proportion of infeasible solutions to feasible and...
void recordLocHeurCall(double runtime)
Reports a real time (measured by a timer) required by HeuristicAlgorithms::heuristicLocationChanges s...
Thrown if the best solution of the heuristic cannot be returned since the solution pool is empty...
Definition: Exceptions.h:141