dignea  1.0.0
Diverse Instance Generator with Novelty Search and Evolutionary Algorithms
AbstractSolver.h
Go to the documentation of this file.
1 
12 #ifndef DIGNEA_ABSTRACTEA_H
13 #define DIGNEA_ABSTRACTEA_H
14 
15 #include <dignea/core/Front.h>
16 #include <dignea/core/Problem.h>
17 #include <dignea/core/Solution.h>
18 #include <dignea/evaluators/PopulationEvaluator.h>
19 #include <dignea/evolution/AvgEvolution.h>
20 #include <dignea/evolution/Evolution.h>
22 #include <dignea/utilities/exceptions/NotImplemented.h>
23 
24 #include <algorithm>
25 #include <array>
26 #include <chrono>
27 #include <cstdio>
28 #include <ctime>
29 #include <iomanip>
30 #include <nlohmann/json.hpp>
31 #include <utility>
32 
33 using json = nlohmann::json;
34 
41 template <class S>
43  public:
45 
46  AbstractSolver(const int &maxEvals, const int &popsize);
47 
48  AbstractSolver(unique_ptr<PopulationEvaluator<S>>, const int &maxEvals,
49  const int &popsize);
50 
51  virtual ~AbstractSolver();
52 
58  virtual void run() = 0;
59 
66  virtual string getName() const = 0;
67 
75  virtual string getID() const = 0;
76 
77  virtual json to_json() const;
78 
85  virtual Front<S> getResults() const = 0;
86 
92  inline int getPopulationSize() const { return populationSize; };
93 
94  void setPopulationSize(int pSize);
95 
101  inline double getElapsedTime() const { return elapsedTime; };
102 
108  inline const vector<S> &getPopulation() const { return population; };
109 
115  int getMaxEvaluations() const { return maxEvaluations; }
116 
122  void setMaxEvaluations(int maxEval) {
124  }
125 
131  const Problem<S> *getProblem() const { return problem.get(); }
132 
139  virtual void setProblem(shared_ptr<Problem<S>> prob) {
140  this->problem = prob;
141  }
142 
149  virtual void setProblem(Problem<S> *prob) { this->problem.reset(prob); }
150 
156  PopulationEvaluator<S> *getEvaluator() const { return evaluator.get(); }
157 
164  void setEvaluator(unique_ptr<PopulationEvaluator<S>> eval) {
165  this->evaluator = move(eval);
166  }
167 
173  int getPerformedEvaluations() const { return performedEvaluations; }
174 
181  void setPerformedEvaluations(int pEvals) {
182  this->performedEvaluations = pEvals;
183  }
184 
190  void setPopulation(const vector<S> &pop);
191 
197  virtual Evolution<S> getEvolution() const;
198 
204  int getPrintingInterval() const { return evolutionInterval; }
205 
206  protected:
213  virtual void initProgress() = 0;
214 
221  virtual void updateProgress() = 0;
222 
229  virtual void finishProgress() = 0;
230 
239  virtual bool isStoppingConditionReached() = 0;
240 
245  virtual void createInitialPopulation() = 0;
246 
252  virtual void evaluatePopulation(vector<S> &pop) = 0;
253 
254  virtual void updateEvolution(vector<S> &pop);
255 
256  virtual void updateEvolution(const int &checkpoint, vector<S> &);
257 
258  protected:
260  int performedEvaluations;
263  // Population of individuals --> Solutions
264  vector<S> population;
265  // Problem to solve
266  shared_ptr<Problem<S>> problem;
267  // Evaluation class
268  unique_ptr<PopulationEvaluator<S>> evaluator;
269  // Evolution data
270  Evolution<S> evolution;
271  AvgEvolution<S> avgEvolution;
272 
273  // Execution time
274  std::chrono::system_clock::time_point startTime;
275  std::chrono::system_clock::time_point endTime;
276  double elapsedTime;
277 
278  // Checkpoints to collect evolution data
279  int nextCheckpoint;
280  int evolutionInterval;
281 
282  public:
283  static const int DEFAULT_POPULATION_SIZE;
284  static const int DEFAULT_EVALUATIONS_LIMIT;
285  static const std::string NAME;
286  static const std::string MAX_EVALUATIONS;
287  static const std::string POP_SIZE;
288  static const std::string ELAPSED_TIME;
289  static const std::string EVALUATOR;
290  static const int EVOLUTION_SIZE;
291 };
292 
298 template <class S>
305 template <class S>
307 template <class S>
308 const std::string AbstractSolver<S>::NAME = "Algorithm";
309 template <class S>
310 const std::string AbstractSolver<S>::MAX_EVALUATIONS = "Max Evaluations";
311 template <class S>
312 const std::string AbstractSolver<S>::POP_SIZE = "Population Size";
313 template <class S>
314 const std::string AbstractSolver<S>::ELAPSED_TIME = "Elapsed Time";
315 template <class S>
316 const std::string AbstractSolver<S>::EVALUATOR = "Evaluator";
317 template <class S>
318 const int AbstractSolver<S>::EVOLUTION_SIZE = 10;
319 
328 template <class S>
330  : maxEvaluations(DEFAULT_EVALUATIONS_LIMIT),
331  performedEvaluations(0),
332  populationSize(DEFAULT_POPULATION_SIZE),
333  elapsedTime(0.0),
334  nextCheckpoint(0) {
335  evolution = {};
336  avgEvolution = {};
337  evolutionInterval = maxEvaluations / EVOLUTION_SIZE;
338 }
339 
348 template <class S>
349 AbstractSolver<S>::AbstractSolver(const int &maxEvals, const int &popsize)
350  : maxEvaluations(maxEvals),
351  performedEvaluations(0),
352  populationSize(popsize),
353  elapsedTime(0.0),
354  nextCheckpoint(0) {
355  evolutionInterval = maxEvaluations / EVOLUTION_SIZE;
356  problem = nullptr;
357  this->evaluator = make_unique<PopulationEvaluator<S>>();
358  evolution = {};
359  avgEvolution = {};
360 }
361 
370 template <class S>
371 AbstractSolver<S>::AbstractSolver(unique_ptr<PopulationEvaluator<S>> eval,
372  const int &maxEvals, const int &popsize)
373  : maxEvaluations(maxEvals),
374  performedEvaluations(0),
375  populationSize(popsize),
376  elapsedTime(0.0),
377  nextCheckpoint(0) {
378  problem = nullptr;
379  evaluator = move(eval);
380  evolution = {};
381  avgEvolution = {};
382  evolutionInterval = maxEvaluations / EVOLUTION_SIZE;
383 }
384 
385 template <class S>
387  population.clear();
388  population.shrink_to_fit();
389 }
390 
398 template <class S>
399 void AbstractSolver<S>::updateEvolution(vector<S> &solutions) {
400  if (nextCheckpoint > maxEvaluations) {
401  string where = "nextCheckpoint > maxEvals(" +
402  to_string(maxEvaluations) +
403  ") in AbstractSolver::updateEvolution with: " +
404  to_string(nextCheckpoint) + " evals";
405  throw(OutOfRange(where));
406  }
407  if (performedEvaluations >= nextCheckpoint) {
408  evolution.update(nextCheckpoint, solutions);
409  avgEvolution.update(nextCheckpoint, solutions);
410  nextCheckpoint += evolutionInterval;
411  }
412 }
413 
422 template <class S>
423 void AbstractSolver<S>::updateEvolution(const int &checkpoint,
424  vector<S> &solutions) {
425  if (checkpoint > (maxEvaluations + evolutionInterval)) {
426  string where =
427  "checkpoint > maxEvals in AbstractSolver::updateEvolution with: " +
428  to_string(checkpoint) +
429  " evals and maxEvals: " + to_string(maxEvaluations);
430  throw(OutOfRange(where));
431  }
432  if (checkpoint >= nextCheckpoint) {
433  evolution.update(checkpoint, solutions);
434  avgEvolution.update(nextCheckpoint, solutions);
435  nextCheckpoint += evolutionInterval;
436  }
437 }
438 
446 template <class S>
447 Evolution<S> AbstractSolver<S>::getEvolution() const {
448  return this->evolution;
449 }
450 
457 template <class S>
459  this->populationSize = pSize;
460  this->population.clear();
461  this->population.reserve(populationSize);
462 }
463 
469 template <class S>
470 void AbstractSolver<S>::setPopulation(const vector<S> &pop) {
471  this->population = pop;
472  this->populationSize = pop.size();
473 }
480 template <class S>
482  json info;
483  Evolution copy = this->evolution;
484  AvgEvolution avgCopy = this->avgEvolution;
485  info["name"] = this->getName();
486  info["max_evals"] = this->maxEvaluations;
487  info["pop_size"] = this->populationSize;
488  info["elapsed_time"] = this->elapsedTime;
489  info["evaluator"] = this->evaluator->getName();
490  info["evolution"] = copy.results();
491  info["avg_evolution"] = avgCopy.results();
492  return info;
493 };
494 
495 #endif // DIGNEA_ABSTRACTEA_H
nlohmann::json json
Definition: MinKnap.h:85
Class to define an Abstract Evolutionary Algorithm. This is the base skeleton for future extensions.
Definition: AbstractSolver.h:42
virtual void createInitialPopulation()=0
Creates the initial population of individuals. Must be implemented in the subclasses to adapt special...
void setPopulation(const vector< S > &pop)
Set the Population.
Definition: AbstractSolver.h:470
virtual void initProgress()=0
Initialises the evolutionary progress. This method must be implemented in the subclasses and should p...
virtual bool isStoppingConditionReached()=0
Check whether the number of performed evaluations has reached the maximum allowed....
int getPopulationSize() const
Get the population size.
Definition: AbstractSolver.h:92
virtual string getID() const =0
Returns the identificator of the algorithm, this is used in the to_json method. Must be implemented i...
double getElapsedTime() const
Get the elapsed time of the evolutionary process.
Definition: AbstractSolver.h:101
virtual void finishProgress()=0
Method which finishes the evolutionary progress. This method must be implemented in the subclasses an...
const Problem< S > * getProblem() const
Gets a pointer to the problem which is being solved.
Definition: AbstractSolver.h:131
void setPerformedEvaluations(int pEvals)
Set the Performed Evaluations. Useful for the updateProgress method.
Definition: AbstractSolver.h:181
virtual void setProblem(Problem< S > *prob)
Set the new problem to solve. Uses a raw pointer and takes the ownership of the object.
Definition: AbstractSolver.h:149
virtual json to_json() const
Generates and returns the JSON representation of the EA.
Definition: AbstractSolver.h:481
static const int DEFAULT_POPULATION_SIZE
Default population size equal to 100 individuals.
Definition: AbstractSolver.h:283
PopulationEvaluator< S > * getEvaluator() const
Gets a pointer to the population evaluator system.
Definition: AbstractSolver.h:156
virtual Front< S > getResults() const =0
Returns a Front object with all the solutions of the evolutionary process. This method must be implem...
int getPrintingInterval() const
Get the interval of checkpoints.
Definition: AbstractSolver.h:204
void setEvaluator(unique_ptr< PopulationEvaluator< S >> eval)
Updates the population evaluator system with the unique_ptr. The method takes the ownership of the ob...
Definition: AbstractSolver.h:164
int getMaxEvaluations() const
Get the maximum number of evaluations to perform.
Definition: AbstractSolver.h:115
virtual string getName() const =0
Returns the name of the algorithm, this is used in the to_json method. Must be implemented in the sub...
virtual void evaluatePopulation(vector< S > &pop)=0
Evaluates the entire population of solutions. This is a virtual method that must be implemented in th...
virtual void updateProgress()=0
Method which updates the evolutionary progress. This method must be implemented in the subclasses and...
const vector< S > & getPopulation() const
Gets a reference of the population.
Definition: AbstractSolver.h:108
virtual Evolution< S > getEvolution() const
Get the Evolution data.
Definition: AbstractSolver.h:447
virtual void setProblem(shared_ptr< Problem< S >> prob)
Set the new problem to solve. Uses a shared_ptr pointer which updates the reference counter....
Definition: AbstractSolver.h:139
void setPopulationSize(int pSize)
Setter to update the population size.
Definition: AbstractSolver.h:458
virtual void run()=0
Main method of the EA. Runs the algorithm but must be implemented in the subclasses.
int getPerformedEvaluations() const
Get the performed evaluations.
Definition: AbstractSolver.h:173
int populationSize
Definition: AbstractSolver.h:261
int maxEvaluations
Definition: AbstractSolver.h:259
static const int DEFAULT_EVALUATIONS_LIMIT
Default evaluation limit equal to 100000 evaluations.
Definition: AbstractSolver.h:284
AbstractSolver()
Construct a new Abstract EA object with default parameter values.
Definition: AbstractSolver.h:329
void setMaxEvaluations(int maxEval)
Set a new maximum number of evaluations to perform.
Definition: AbstractSolver.h:122
virtual void updateEvolution(vector< S > &pop)
Definition: AbstractSolver.h:399
Front class which stores the final results of an EA execution.
Definition: Front.h:26
Class to represent a Problem in the tool. It includes the basic information for a problem a few metho...
Definition: Problem.h:29