dignea  1.0.0
Diverse Instance Generator with Novelty Search and Evolutionary Algorithms
AbstractGA.h
Go to the documentation of this file.
1 
11 #ifndef DIGNEA_ABSTRACTGA_H
12 #define DIGNEA_ABSTRACTGA_H
13 
14 #include <dignea/core/Crossover.h>
15 #include <dignea/core/Mutation.h>
16 #include <dignea/core/Problem.h>
17 #include <dignea/core/Replacement.h>
18 #include <dignea/core/Selection.h>
19 #include <dignea/evaluators/PopulationEvaluator.h>
20 #include <dignea/utilities/exceptions/NoMOAllowed.h>
21 #include <dignea/utilities/random/PseudoRandom.h>
22 
23 #include <memory>
24 #include <vector>
25 
26 #include "AbstractEA.h"
27 
28 using namespace std;
29 
37 template <class S>
38 class AbstractGA : public AbstractEA<S> {
39  public:
40  AbstractGA();
41 
42  virtual ~AbstractGA() = default;
43 
44  virtual string getName() const = 0;
45 
46  json to_json() const override;
47 
48  virtual Front<S> getResults() const;
49 
50  void run() override;
51 
52  void setProblem(shared_ptr<Problem<S>> prob) override;
53 
54  void setProblem(Problem<S> *prob) override;
55 
56  protected:
57  virtual void initProgress();
58 
59  virtual void updateProgress() = 0;
60 
61  virtual void finishProgress();
62 
63  virtual bool isStoppingConditionReached();
64 
65  virtual void createInitialPopulation();
66 
67  virtual void evaluatePopulation(vector<S> &pop);
68 
69  virtual vector<S> createMating();
70 
71  virtual void reproduction(S &, S &);
72 
73  public:
74  double getMutationRate() const;
75 
76  void setMutationRate(double mutationRate);
77 
78  double getCrossRate() const;
79 
80  void setCrossRate(double crossRate);
81 
82  const Mutation<S> *getMutation() const;
83 
84  void setMutation(unique_ptr<Mutation<S>> mutation);
85 
86  const Crossover<S> *getCrossover() const;
87 
88  void setCrossover(unique_ptr<Crossover<S>> crossover);
89 
90  const Selection<S> *getSelection() const;
91 
92  void setSelection(unique_ptr<Selection<S>> selectionOperator);
93 
94  protected:
95  double mutationRate;
96  double crossRate;
98  unique_ptr<Mutation<S>> mutation;
99  unique_ptr<Crossover<S>> crossover;
100  unique_ptr<Selection<S>> selection;
101  unique_ptr<Replacement<S>> replacement;
103  public:
104  static double DEFAULT_MUTATION_RATE;
105  static double DEFAULT_CROSSOVER_RATE;
107 };
108 
114 template <class S>
121 template <class S>
123 
129 template <class S>
131 
138 template <class S>
140  : AbstractEA<S>(),
141  mutationRate(DEFAULT_MUTATION_RATE),
142  crossRate(DEFAULT_CROSSOVER_RATE) {
144  this->mutation = nullptr;
145  this->crossover = nullptr;
146  this->selection = nullptr;
147  this->evaluator = make_unique<PopulationEvaluator<S>>();
148 }
149 
156 template <class S>
158  this->population.resize(this->populationSize);
159  for (int i = 0; i < this->getPopulationSize(); i++) {
160  this->population[i] = this->problem->createSolution();
161  }
162  // Usamos el método por si empleamos un evaluador paralelo
163  this->evaluatePopulation(this->population);
164  // Reseteamos el printingcheck --> Para el uso de repeticiones en los
165  // experimentos
166  this->nextCheckpoint = 0;
167  this->updateEvolution(0, this->population);
168  this->initProgress();
169 }
170 
178 template <class S>
179 void AbstractGA<S>::evaluatePopulation(vector<S> &pop) {
180  this->evaluator->evaluate(pop, this->problem.get());
181 }
182 
191 template <class S>
193  return (this->performedEvaluations >= this->maxEvaluations);
194 }
195 
204 template <class S>
206  this->performedEvaluations = this->populationSize;
207 }
208 
222 template <class S>
224  if (this->problem) {
225  this->createInitialPopulation();
226  this->startTime = chrono::system_clock::now();
227  while (!this->isStoppingConditionReached()) {
228  vector mating = this->createMating();
229  this->evaluatePopulation(mating);
230  this->population = replacement->replace(this->population, mating);
231  this->updateProgress();
232  this->updateEvolution(this->performedEvaluations, this->population);
233  }
234  this->endTime = chrono::system_clock::now();
235  this->finishProgress();
236  } else {
237  throw std::runtime_error("Problem is not set in GA::run");
238  }
239 }
240 
249 template <class S>
251  vector<S> offspring(this->populationSize);
252  for (int i = 0; i < this->populationSize; i++) {
253  S child1 = selection->select(this->population);
254  S child2 = selection->select(this->population);
255  reproduction(child1, child2);
256  offspring[i] = child1;
257  }
258  return offspring;
259 }
260 
269 template <class S>
270 void AbstractGA<S>::reproduction(S &child1, S &child2) {
271  // Cruzamos los individuos con cierta probabilidad
272  if (PseudoRandom::randDouble() < crossRate) {
273  crossover->run(child1, child2);
274  }
275  mutation->run(child1, mutationRate, this->problem.get());
276 }
277 
284 template <class S>
286  return mutationRate;
287 }
288 
295 template <class S>
296 void AbstractGA<S>::setMutationRate(double mutationRate) {
297  AbstractGA::mutationRate = mutationRate;
298 }
299 
306 template <class S>
308  return crossRate;
309 }
310 
317 template <class S>
318 void AbstractGA<S>::setCrossRate(double crossRate) {
319  AbstractGA::crossRate = crossRate;
320 }
321 
328 template <class S>
330  return mutation.get();
331 }
332 
340 template <class S>
341 void AbstractGA<S>::setMutation(unique_ptr<Mutation<S>> newMut) {
342  this->mutation = move(newMut);
343 }
344 
351 template <class S>
353  return crossover.get();
354 }
355 
363 template <class S>
364 void AbstractGA<S>::setCrossover(unique_ptr<Crossover<S>> newCX) {
365  this->crossover = move(newCX);
366 }
367 
374 template <class S>
376  return selection.get();
377 }
378 
386 template <class S>
387 void AbstractGA<S>::setSelection(unique_ptr<Selection<S>> newSelection) {
388  this->selection = move(newSelection);
389 }
390 
398 template <class S>
399 void AbstractGA<S>::setProblem(shared_ptr<Problem<S>> prob) {
400  if (prob->getNumberOfObjs() != 1) {
401  std::string where = "AbstractGA setProblem";
402  throw(NoMOAllowed(where));
403  }
404  this->problem = prob;
405 }
413 template <class S>
415  if (prob->getNumberOfObjs() != 1) {
416  std::string where = "AbstractGA setProblem";
417  throw(NoMOAllowed(where));
418  }
419  this->problem.reset(prob);
420 }
421 
427 template <class S>
429  std::chrono::duration<double> diff = this->endTime - this->startTime;
430  this->elapsedTime = diff.count();
431 }
432 
441 template <class S>
443  if (!this->population.empty()) {
444  vector<S> results;
445  // Incluimos solo los individuos factibles
446  for (const S &individual : this->population) {
447  if (individual.getConstraintCoeff() == 0.0) {
448  results.push_back(S(individual));
449  }
450  }
451  results.erase(unique(results.begin(), results.end()), results.end());
452  return Front<S>(results);
453  } else
454  return Front<S>(0);
455 }
456 
462 template <class S>
464  json data = AbstractEA<S>::to_json();
465  if (mutation) data["mutation"] = this->mutation->getName();
466  if (crossover) data["crossover"] = this->crossover->getName();
467  if (selection) data["selection"] = this->selection->getName();
468  if (replacement) data["replacement"] = this->replacement->getName();
469  data["mutation_rate"] = this->mutationRate;
470  data["crossover_rate"] = this->crossRate;
471  return data;
472 }
473 
474 #endif // DIGNEA_ABSTRACTGA_H
Class to define an Abstract Evolutionary Algorithm. This is the base skeleton for future extensions.
Definition: AbstractEA.h:42
virtual json to_json() const
Generates and returns the JSON representation of the EA.
Definition: AbstractEA.h:481
int populationSize
Definition: AbstractEA.h:261
Class to represent an Abstract Genetic Algorithm. Base skeleton is defined here, to extend in particu...
Definition: AbstractGA.h:38
static int DEFAULT_POPULATION_SIZE
Default population size to GAs set to 32 individuals.
Definition: AbstractGA.h:106
json to_json() const override
Creates and returns JSON object with the GA information.
Definition: AbstractGA.h:463
void run() override
Runs the evolutionary process. This is the main EA method. This methods is in charge of:
Definition: AbstractGA.h:223
void setProblem(shared_ptr< Problem< S >> prob) override
Uptades the problem to solve using a share_ptr. The problem must be single-objective.
Definition: AbstractGA.h:399
virtual void updateProgress()=0
Method which updates the evolutionary progress. This method must be implemented in the subclasses and...
const Mutation< S > * getMutation() const
Gets a pointer to the mutation operator.
Definition: AbstractGA.h:329
virtual vector< S > createMating()
Generates the mating population of individuals to be evaluated. The individuals are selected and afte...
Definition: AbstractGA.h:250
virtual void initProgress()
Starts the evolutionary process. By default this methods sets the number of performed evaluations to ...
Definition: AbstractGA.h:205
const Crossover< S > * getCrossover() const
Returns a raw pointer to the crossover operator.
Definition: AbstractGA.h:352
AbstractGA()
Creates a new AbstractGA which initialises all parameter to default. The operators will be set to nul...
Definition: AbstractGA.h:139
void setCrossRate(double crossRate)
Updates the crossover rate.
Definition: AbstractGA.h:318
double crossRate
Definition: AbstractGA.h:96
static double DEFAULT_CROSSOVER_RATE
Default crossover rate to GAs set to 0.8.
Definition: AbstractGA.h:105
const Selection< S > * getSelection() const
Returns a raw pointer of the selection operator.
Definition: AbstractGA.h:375
virtual void evaluatePopulation(vector< S > &pop)
Evaluates the entire population of individuals using the problem evaluation function.
Definition: AbstractGA.h:179
void setMutation(unique_ptr< Mutation< S >> mutation)
Updates the mutation operator. Takes a unique_ptr pointing to the new Mutation operator and takes the...
Definition: AbstractGA.h:341
virtual void reproduction(S &, S &)
Applies the genetic operator. This methods is invoked from createMating.
Definition: AbstractGA.h:270
double mutationRate
Definition: AbstractGA.h:95
virtual void createInitialPopulation()
Creates the initial population of individuals before starting the evolutionary process.
Definition: AbstractGA.h:157
static double DEFAULT_MUTATION_RATE
Default mutation rate for GAs set to 0.05.
Definition: AbstractGA.h:104
virtual bool isStoppingConditionReached()
Checks whether the evolutionary process has reached the maximum limit.
Definition: AbstractGA.h:192
unique_ptr< Selection< S > > selection
Definition: AbstractGA.h:100
void setCrossover(unique_ptr< Crossover< S >> crossover)
Updates the crossover operator. Takes a unique_ptr pointing to the new Crossover operator and takes t...
Definition: AbstractGA.h:364
virtual void finishProgress()
Finishes the evolutionary process by computing the elapsed time.
Definition: AbstractGA.h:428
unique_ptr< Replacement< S > > replacement
Definition: AbstractGA.h:101
unique_ptr< Mutation< S > > mutation
Definition: AbstractGA.h:98
virtual Front< S > getResults() const
Returns a front with the feasible non repeated individuals in the last population of the Genetic Algo...
Definition: AbstractGA.h:442
void setSelection(unique_ptr< Selection< S >> selectionOperator)
Updates the selection operator. Takes a unique_ptr pointing to the new Selection operator and takes t...
Definition: AbstractGA.h:387
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...
double getCrossRate() const
Gets the crossover rate.
Definition: AbstractGA.h:307
void setMutationRate(double mutationRate)
Updates the mutation rate.
Definition: AbstractGA.h:296
double getMutationRate() const
Gets the mutation rate.
Definition: AbstractGA.h:285
unique_ptr< Crossover< S > > crossover
Definition: AbstractGA.h:99
Abstract Crossover interface.
Definition: Crossover.h:19
Front class which stores the final results of an EA execution.
Definition: Front.h:26
Abstract Mutation interface.
Definition: Mutation.h:21
Class to represent a Problem in the tool. It includes the basic information for a problem a few metho...
Definition: Problem.h:29
int getNumberOfObjs() const
Get the number of objectives of the problem.
Definition: Problem.h:135
static double randDouble()
Generates a random double value between 0.0 and 1.0.
Definition: PseudoRandom.cpp:31
Abstract Selection interface.
Definition: Selection.h:21