dignea  1.0.0
Diverse Instance Generator with Novelty Search and Evolutionary Algorithms
SimulatedAnnealing.h
1 //
2 // Created by amarrero on 25/6/21.
3 //
4 
5 #ifndef DIGNEA_SIMULATEDANNEALING_H
6 #define DIGNEA_SIMULATEDANNEALING_H
7 
9 #include <dignea/utilities/exceptions/NoMOAllowed.h>
10 #include <dignea/utilities/random/PseudoRandom.h>
11 
12 #include <cmath>
13 #include <vector>
14 
15 using namespace std;
16 
22 template <class S>
23 class SimulatedAnnealing : public AbstractEA<S> {
24  public:
25  SimulatedAnnealing(const int &maxEvaluations, const float &initialTemp,
26  const float &tempVariation);
27 
28  virtual ~SimulatedAnnealing() = default;
29 
30  void run() override;
36  string getName() const override { return "Simulated Annealing"; };
42  string getID() const override { return "SA"; }
43 
44  Front<S> getResults() const override;
45 
46  void setProblem(shared_ptr<Problem<S>> prob) override;
47 
48  void setProblem(Problem<S> *prob) override;
54  float getTempVariation() const { return tempVariation; }
60  void setTempVariation(float tempVariation) {
61  SimulatedAnnealing::tempVariation = tempVariation;
62  }
68  float getCurrentTemp() const { return currentTemp; }
74  void setCurrentTemp(float currentTemp) {
75  SimulatedAnnealing::currentTemp = currentTemp;
76  }
77 
78  void setPopulationSize(const int &pSize);
79 
80  protected:
81  void initProgress() override;
82 
83  void updateProgress() override;
84 
85  void finishProgress() override;
86 
87  bool isStoppingConditionReached() override;
88 
89  void createInitialPopulation() override;
90 
91  void evaluatePopulation(vector<S> &vector1) override{};
92 
93  S evaluateInds(S &popInd, S &offspring);
94 
95  private:
96  S applyPerturbations();
97 
98  void updateTemp() { currentTemp *= tempVariation; }
99 
100  private:
101  float tempVariation;
102  float currentTemp;
103 };
104 
113 template <class S>
115  const float &initialTemp,
116  const float &tempVariation)
117  : AbstractEA<S>(maxEvaluations, 1),
118  tempVariation(tempVariation),
119  currentTemp(initialTemp) {}
120 
126 template <class S>
128  if (this->problem) {
129  this->createInitialPopulation();
130  this->startTime = chrono::system_clock::now();
131  while (!this->isStoppingConditionReached()) {
132  S offspring = applyPerturbations();
133  this->population[0] = evaluateInds(this->population[0], offspring);
134  updateTemp();
135  this->updateProgress();
136  }
137  this->endTime = chrono::system_clock::now();
138  this->finishProgress();
139  } else {
140  throw std::runtime_error("Problem is not set in SA::run");
141  }
142 }
143 
151 template <class S>
153  return Front<S>(this->population);
154 }
155 
162 template <class S>
164  this->performedEvaluations = 1;
165 }
166 
173 template <class S>
175  this->performedEvaluations += 2;
176 }
177 
183 template <class S>
185  std::chrono::duration<double> diff = this->endTime - this->startTime;
186  this->elapsedTime = diff.count();
187 }
188 
196 template <class S>
198  return (this->performedEvaluations >= this->maxEvaluations);
199 }
200 
207 template <class S>
209  this->population.resize(1);
210  this->population[0] = this->problem->createSolution();
211  this->evaluatePopulation(this->population);
212  this->nextCheckpoint = 0;
213  this->updateEvolution(0, this->population);
214  this->initProgress();
215 }
216 
225 template <class S>
226 S SimulatedAnnealing<S>::evaluateInds(S &popInd, S &offspring) {
227  this->evaluator->evaluate(popInd, this->problem.get());
228  this->evaluator->evaluate(offspring, this->problem.get());
229  double diff = offspring.getFitness() - popInd.getFitness();
230  if (diff < 0.0) {
231  return offspring;
232  } else {
233  const double randProb = PseudoRandom::randDouble();
234  const double e = exp(-diff / this->currentTemp);
235  const double prob = min(1.0, e);
236  return (randProb < prob) ? offspring : popInd;
237  }
238 }
239 
247 template <class S>
249  S offspring = this->population[0];
250  double pert = PseudoRandom::randDouble();
251  vector vars = offspring.getVariables();
252  for (unsigned int i = 0; i < vars.size(); i++) {
253  double newValue = pert * (this->problem->getUpperLimit(i) -
254  this->problem->getLowerLimit(i)) +
255  this->problem->getLowerLimit(i);
256  vars[i] = newValue;
257  }
258  offspring.setVariables(vars);
259  return offspring;
260 }
261 
268 template <class S>
270  if (prob->getNumberOfObjs() != 1) {
271  std::string where = "SimulatedAnnealing setProblem";
272  throw(NoMOAllowed(where));
273  }
274  this->problem = prob;
275 }
276 
283 template <class S>
285  if (prob->getNumberOfObjs() != 1) {
286  std::string where = "SimulatedAnnealing setProblem";
287  throw(NoMOAllowed(where));
288  }
289  this->problem.reset(prob);
290 }
291 
299 template <class S>
301  std::string where = "SimulatedAnnealing setPopulationSize";
302  throw(NotImplemented(where));
303 }
304 
305 #endif // DIGNEA_SIMULATEDANNEALING_H
Class to define an Abstract Evolutionary Algorithm. This is the base skeleton for future extensions.
Definition: AbstractEA.h:42
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
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
Simulated Annealing Algorithm.
Definition: SimulatedAnnealing.h:23
void evaluatePopulation(vector< S > &vector1) override
Evaluates the entire population of solutions. This is a virtual method that must be implemented in th...
Definition: SimulatedAnnealing.h:91
void run() override
Runs the Simulated Annealing algorithm during maxEvaluations.
Definition: SimulatedAnnealing.h:127
void setTempVariation(float tempVariation)
Set the temperature variation constant for each generation.
Definition: SimulatedAnnealing.h:60
Front< S > getResults() const override
Returns the results obtained by the SA algorithm at the end of the process.
Definition: SimulatedAnnealing.h:152
void finishProgress() override
Finishes the evolutionary process and computes the elapsed time.
Definition: SimulatedAnnealing.h:184
S evaluateInds(S &popInd, S &offspring)
Evaluates the parent and offspring individuals at each generation.
Definition: SimulatedAnnealing.h:226
void initProgress() override
Initialises the evolutionary process. Sets the number of performedEvaluations to 1.
Definition: SimulatedAnnealing.h:163
string getID() const override
Get the ID of the algorithm.
Definition: SimulatedAnnealing.h:42
string getName() const override
Get the Name.
Definition: SimulatedAnnealing.h:36
float getCurrentTemp() const
Get the current temperature.
Definition: SimulatedAnnealing.h:68
void setPopulationSize(const int &pSize)
This methods is not implemented for this class. The population size of a SA algorithm is always 1.
Definition: SimulatedAnnealing.h:300
bool isStoppingConditionReached() override
Checks whether the maximum number of evaluations have been performed.
Definition: SimulatedAnnealing.h:197
float getTempVariation() const
Get the temperature variation constant for each generation.
Definition: SimulatedAnnealing.h:54
void setProblem(shared_ptr< Problem< S >> prob) override
Sets the problem to solve using Simulated Annealing.
Definition: SimulatedAnnealing.h:269
void createInitialPopulation() override
Creates the initial population for the SA. The population of the SA is just one individual.
Definition: SimulatedAnnealing.h:208
void updateProgress() override
Updates the evolutionary process by increasing the performedEvaluations in two.
Definition: SimulatedAnnealing.h:174
void setCurrentTemp(float currentTemp)
Set the current temperature of the process.
Definition: SimulatedAnnealing.h:74
SimulatedAnnealing(const int &maxEvaluations, const float &initialTemp, const float &tempVariation)
Construct a new Simulated Annealing object with all the parameters.
Definition: SimulatedAnnealing.h:114