16 #include <dignea/core/Crossover.h>
17 #include <dignea/core/Mutation.h>
18 #include <dignea/core/Replacement.h>
19 #include <dignea/core/Selection.h>
21 #include <dignea/distances/Euclidean.h>
23 #include <dignea/generator/evaluations/EasyInstances.h>
24 #include <dignea/generator/evaluations/InstanceFitness.h>
25 #include <dignea/generator/evaluations/Weighted.h>
26 #include <dignea/metrics/AverageFitness.h>
27 #include <dignea/metrics/BestFitness.h>
30 #include <dignea/searches/NSFeatures.h>
31 #include <dignea/searches/NoveltySearch.h>
33 #include <dignea/utilities/exceptions/Mismatch.h>
34 #include <dignea/utilities/random/PseudoRandom.h>
54 template <
typename IP,
typename IS,
typename OP,
typename OS>
67 EIG(
const float &fitness = 0.6f,
const float &novelty = 0.4f);
69 virtual ~
EIG() =
default;
73 [[nodiscard]] json to_json()
const override;
77 [[nodiscard]]
string getName()
const override {
return "EIG"; };
80 [[nodiscard]]
string getID()
const override {
return getName(); };
82 virtual Front<IS> getResults()
const override;
90 void setInstanceProblem(unique_ptr<IP> problem);
94 vector<Alg *> getPortfolio()
const;
104 void setPortfolio(vector<unique_ptr<Alg>> &configs);
155 this->mutation = move(mut);
164 this->crossover = move(cx);
173 this->selection = move(sel);
179 this->repOperator = move(rep);
188 return instanceFitness.get();
193 this->instanceFitness = move(eval);
203 return noveltySearch.get();
208 this->noveltySearch = move(noveltySearch);
215 this->weightedFitness = make_unique<Weighted<IS>>(fW, nW);
219 void initProgress()
override;
221 void updateProgress()
override;
223 void finishProgress()
override;
225 bool isStoppingConditionReached()
override;
227 void createInitialPopulation()
override;
229 void evaluatePopulation(vector<IS> &individuals)
override;
231 [[maybe_unused]]
void evaluateIndividual(IS &individual);
233 virtual void evaluationPhase(vector<IS> &individuals);
235 virtual void reproduction(IS &solution, IS &solution2);
237 virtual void replacement(vector<IS> &individuals);
239 virtual void updateEvolution(vector<IS> &solutions);
243 vector<unique_ptr<Alg>>
249 unique_ptr<Replacement<IS>> repOperator;
256 unique_ptr<InstanceFitness> instanceFitness;
257 unique_ptr<Weighted<IS>> weightedFitness;
273 template <
typename IP,
typename IS,
typename OP,
typename OS>
282 instanceFitness = make_unique<EasyInstances>();
283 weightedFitness = make_unique<Weighted<IS>>(fitness, novelty);
284 noveltySearch = make_unique<NSFeatures<IS>>(make_unique<Euclidean<float>>(),
286 this->evolutionInterval = 1;
297 template <
typename IP,
typename IS,
typename OP,
typename OS>
301 std::cout <<
"Running EIG" << std::endl;
305 this->repOperator = make_unique<FirstImprove<IS>>();
307 createInitialPopulation();
308 this->startTime = chrono::system_clock::now();
309 vector<IS> offspring(this->populationSize);
310 while (!isStoppingConditionReached()) {
312 std::cout <<
"Performing Generation " << this->performedEvaluations
315 for (
int i = 0; i < this->populationSize; i++) {
316 IS firstChild = selection->select(this->population);
317 IS secondChild = selection->select(this->population);
318 reproduction(firstChild, secondChild);
319 offspring[i] = firstChild;
321 evaluationPhase(offspring);
322 replacement(offspring);
324 this->updateEvolution(this->population);
327 this->endTime = chrono::system_clock::now();
330 throw std::logic_error(
"AbstractDomain not set in EIG::run");
344 template <
typename IP,
typename IS,
typename OP,
typename OS>
346 if (this->performedEvaluations % 10 == 0) {
347 this->evolution.update(this->performedEvaluations, solutions);
348 this->avgEvolution.update(this->performedEvaluations, solutions);
369 template <
typename IP,
typename IS,
typename OP,
typename OS>
372 evaluatePopulation(individuals);
374 individuals = noveltySearch->run(individuals, this->instProb.get());
377 auto [fRatio, nRatio] = this->weightedFitness->getFAndNRatios();
378 std::cout << fmt::format(
"{:=^120}",
"") << std::endl;
379 std::cout << fmt::format(
"{:^20}({})\t{:^20}({})\t{:^20}",
380 "Performance Score ", fRatio,
"Diversity Score ",
383 std::cout << fmt::format(
"{:=^120}",
"") << std::endl;
385 weightedFitness->computeFitness(individuals);
397 template <
typename IP,
typename IS,
typename OP,
typename OS>
399 return noveltySearch->getResults();
409 template <
typename IP,
typename IS,
typename OP,
typename OS>
411 this->performedEvaluations = 0;
422 template <
typename IP,
typename IS,
typename OP,
typename OS>
424 this->performedEvaluations++;
434 template <
typename IP,
typename IS,
typename OP,
typename OS>
436 std::chrono::duration<double> diff = this->endTime - this->startTime;
437 this->elapsedTime = diff.count();
449 template <
typename IP,
typename IS,
typename OP,
typename OS>
451 return (this->performedEvaluations >= this->maxEvaluations);
462 template <
typename IP,
typename IS,
typename OP,
typename OS>
464 this->population.reserve(this->populationSize);
465 this->population = instProb->createSolutions(this->populationSize);
466 evaluatePopulation(this->population);
469 noveltySearch->run(this->population, this->instProb.get());
471 weightedFitness->computeFitness(this->population);
472 this->updateEvolution(this->population);
486 template <
typename IP,
typename IS,
typename OP,
typename OS>
488 instProb->beforeEvaluation(individuals);
489 for (IS &individual : individuals) {
491 shared_ptr<OP> optProblem = instProb->genOptProblem(individual);
493 vector<float> avgBestFitEAs;
494 avgBestFitEAs.reserve(algPortfolio.size());
495 vector<vector<float>> bestSolsEAs;
497 for (unique_ptr<Alg> &config : algPortfolio) {
498 vector<float> bestF(repetitions, 0.0);
500 for (
int rep = 0; rep < repetitions; rep++) {
501 config->setProblem(optProblem);
505 OS bestSolution = bestFitness.getBestSolution(front);
506 bestF[rep] = bestSolution.getFitness();
509 float averageBestFitness = averageFitness.computeValue(bestF);
510 avgBestFitEAs.push_back(averageBestFitness);
512 bestSolsEAs.push_back(bestF);
516 individual.setConfigFitness(bestSolsEAs);
517 individual.setAvgConfigFitness(avgBestFitEAs);
520 individual.setBiasedFitness(
521 this->instanceFitness->compute(avgBestFitEAs));
525 instProb->afterEvaluation(individuals);
538 template <
typename IP,
typename IS,
typename OP,
typename OS>
541 shared_ptr<OP> optProblem = instProb->genOptProblem(individual);
542 vector<float> allFitness;
543 allFitness.reserve(algPortfolio.size());
544 for (unique_ptr<Alg> &config : algPortfolio) {
546 for (
int rep = 0; rep < repetitions; rep++) {
547 config->setProblem(optProblem);
550 OS bestSolution = bestFitness.getBestSolution(front);
554 float averageBestFitness = averageFitness.computeValue(solutions);
555 allFitness.push_back(averageBestFitness);
557 individual.setBiasedFitness(instanceFitness->compute(allFitness));
570 template <
typename IP,
typename IS,
typename OP,
typename OS>
574 this->crossover->run(solution1, solution2);
576 this->mutation->run(solution1, this->mutationRate, this->instProb.get());
589 template <
typename IP,
typename IS,
typename OP,
typename OS>
591 if (individuals.size() != this->population.size()) {
592 std::string where =
" replacement at EIG";
593 throw(Mismatch(where));
595 const float probIncl = this->populationSize / 100.0;
596 for (
int i = 0; i < this->populationSize; i++) {
597 if (this->population[i].getDiversity() >=
598 this->noveltySearch->getThreshold() ||
600 (this->population[i].getBiasedFitness() > 0))) {
602 this->noveltySearch->insertIntoArchive(this->population[i]);
606 this->noveltySearch->cmpFinals(this->population);
609 this->repOperator->replace(this->population, individuals);
621 template <
typename IP,
typename IS,
typename OP,
typename OS>
623 algPortfolio.clear();
624 algPortfolio.reserve(configs.size());
625 for (
unsigned int i = 0; i < configs.size(); i++) {
626 algPortfolio.push_back(move(configs[i]));
638 template <
typename IP,
typename IS,
typename OP,
typename OS>
640 this->instProb = move(problem);
651 template <
typename IP,
typename IS,
typename OP,
typename OS>
653 vector<Alg *> configurations;
654 configurations.reserve(algPortfolio.size());
655 for (
const unique_ptr<Alg> &config : algPortfolio) {
656 configurations.push_back(config.get());
658 return configurations;
669 template <
typename IP,
typename IS,
typename OP,
typename OS>
672 Evolution copy = this->evolution;
673 AvgEvolution avgCopy = this->avgEvolution;
674 data[
"name"] = this->getName();
675 data[
"max_generations"] = this->getMaxEvaluations();
676 data[
"repetitions"] = this->repetitions;
677 data[
"pop_size"] = this->populationSize;
678 data[
"mutation"] = this->mutation->getName();
679 data[
"crossover"] = this->crossover->getName();
680 data[
"replacement"] = this->repOperator->getName();
681 data[
"mutation_rate"] = this->mutationRate;
682 data[
"crossover_rate"] = this->crossoverRate;
683 data[
"elapsed_time"] = this->elapsedTime;
684 data[
"evolution"] = copy.results();
685 data[
"avg_evolution"] = avgCopy.results();
686 data[
"novelty_search"] = this->noveltySearch->to_json();
687 auto [fRatio, nRatio] = this->weightedFitness->getFAndNRatios();
688 data[
"weighted_function"][
"fitness_ratio"] = fRatio;
689 data[
"weighted_function"][
"novelty_ratio"] = nRatio;
692 for (
const unique_ptr<Alg> &config : this->algPortfolio) {
693 data[
"portfolio"][i] = config->to_json();
694 data[
"portfolio"][i][
"isTarget"] = target;
Class to define an Abstract Evolutionary Algorithm. This is the base skeleton for future extensions.
Definition: AbstractEA.h:42
int maxEvaluations
Definition: AbstractEA.h:259
Abstract Crossover interface.
Definition: Crossover.h:19
Instance Generation Algorithm. Known as Meta-Evolutionary Algorithm (EIG). This algorithm uses a Weig...
Definition: EIG.h:55
void setInstanceProblem(unique_ptr< IP > problem)
Set the Instance Generation Problem.
Definition: EIG.h:639
void setReplacement(unique_ptr< Replacement< IS >> rep)
Set the selection operator. Takes ownership of the pointer.
Definition: EIG.h:178
BestFitness< OS > bestFitness
Definition: EIG.h:262
void setInstanceFitness(unique_ptr< InstanceFitness > eval)
Set the evaluation approach for the instances.
Definition: EIG.h:192
int repetitions
Definition: EIG.h:253
float getMutationRate() const
Get the mutation rate used in EIG for mutation instances during the evolutionary process.
Definition: EIG.h:112
float mutationRate
Definition: EIG.h:251
AverageFitness< OS > averageFitness
Definition: EIG.h:259
void run() override
Interface to run the EIG for generating a set of instances for the optimisation problem defined (OP)
Definition: EIG.h:298
virtual void updateEvolution(vector< IS > &solutions)
Updates the evolution results of the algorithm for the given checkpoint.
Definition: EIG.h:345
void setCrossover(unique_ptr< Crossover< IS >> cx)
Set the crossover operator. Takes ownership of the pointer.
Definition: EIG.h:163
void setMutationRate(float mRate)
Set the mutation rate used in EIG for mutation instances during the evolutionary process.
Definition: EIG.h:117
virtual void reproduction(IS &solution, IS &solution2)
Executes the genetic operator over two instances to generate new individuals.
Definition: EIG.h:571
virtual void replacement(vector< IS > &individuals)
Replacement method for the population. In this case, the replacement is a simple generational approac...
Definition: EIG.h:590
float crossoverRate
Definition: EIG.h:252
void setSelection(unique_ptr< Selection< IS >> sel)
Set the selection operator. Takes ownership of the pointer.
Definition: EIG.h:172
void updateProgress() override
Updates the evolution by increasing the number of generations performed.
Definition: EIG.h:423
vector< unique_ptr< Alg > > algPortfolio
Definition: EIG.h:244
void evaluateIndividual(IS &individual)
Evaluates the given IS with all the algorithms in the porftolio.
Definition: EIG.h:539
float getCrossoverRate() const
Get the crossover rate used in EIG for applying the crossover operator to instances during the evolut...
Definition: EIG.h:125
unique_ptr< Mutation< IS > > mutation
Definition: EIG.h:246
int getRepetitions() const
Get the number of repetitions that each algorithm in the portfolio must perform over each instance at...
Definition: EIG.h:138
Selection< IS > * getSelection() const
Get the selection operator.
Definition: EIG.h:168
json to_json() const override
Creates the JSON representation of the EIG.
Definition: EIG.h:670
void finishProgress() override
Finishes the execution of the EIG.
Definition: EIG.h:435
unique_ptr< NoveltySearch< IS > > noveltySearch
Definition: EIG.h:255
void setPortfolio(vector< unique_ptr< Alg >> &configs)
Set the portfolio of algorithms to use in the evolutionary process. The order of the algorithms in th...
Definition: EIG.h:622
virtual void evaluationPhase(vector< IS > &individuals)
Evaluation phase of the EIG All the stages necessary to evaluated the population of individuals are p...
Definition: EIG.h:370
Mutation< IS > * getMutation() const
Get the mutation operator used to mutate instances in EIG.
Definition: EIG.h:150
void createInitialPopulation() override
Creates a initial population of Problem Instances of the OP type. Uses the IP method "createSolutions...
Definition: EIG.h:463
bool isStoppingConditionReached() override
Checks whether the number of performed generations has reached the maximum allowed.
Definition: EIG.h:450
void setRepetitions(int reps)
Set the number of repetitions that each algorithm in the portfolio must perform over each instance at...
Definition: EIG.h:146
InstanceFitness * getEvaluation() const
Get the evaluation approach for the instances.
Definition: EIG.h:187
void setCrossoverRate(float cRate)
Set the crossover rate used in EIG for applying the crossover operator to instances during the evolut...
Definition: EIG.h:130
void setNoveltySearch(unique_ptr< NoveltySearch< IS >> noveltySearch)
Set the Novelty Search approach to use.
Definition: EIG.h:207
unique_ptr< IP > instProb
Definition: EIG.h:242
unique_ptr< Crossover< IS > > crossover
Definition: EIG.h:247
void setMutation(unique_ptr< Mutation< IS >> mut)
Set the mutation operator. Takes ownership of the pointer.
Definition: EIG.h:154
void setWeightedFunction(const float &fW, const float &nW)
Set the weights to use in the WFF.
Definition: EIG.h:214
virtual Front< IS > getResults() const override
Returns a set of individuals as a result of the evolutionary method. The individual are instances for...
Definition: EIG.h:398
void evaluatePopulation(vector< IS > &individuals) override
Evaluates the population of individuals with all the algorithms in the portfolio.
Definition: EIG.h:487
string getID() const override
Get the ID. Similar to getName.
Definition: EIG.h:80
void initProgress() override
Initialises the number of generations performed to 0.
Definition: EIG.h:410
string getName() const override
Get the name of the algorithm.
Definition: EIG.h:77
const NoveltySearch< IS > * getNoveltySearch() const
Get the Novelty Search approach used in EIG.
Definition: EIG.h:202
Crossover< IS > * getCrossover() const
Get the crossover operator used in EIG.
Definition: EIG.h:159
vector< Alg * > getPortfolio() const
Get the portfolio of algorithms used in the evolutionary process.
Definition: EIG.h:652
EIG(const float &fitness=0.6f, const float &novelty=0.4f)
Construct a new EIG object using a fitness ratio of 0.6 and novelty of 0.4 by default....
Definition: EIG.h:274
const IP * getInstanceProblem() const
Get a raw pointer to the Instance Generation Problem.
Definition: EIG.h:86
unique_ptr< Selection< IS > > selection
Definition: EIG.h:248
int getGenerations()
Get the number of generations that EIG must perform.
Definition: EIG.h:198
Front class which stores the final results of an EA execution.
Definition: Front.h:26
void addSolution(const S &solution)
Includes a new solution in the front. This is only for single-objective solutions.
Definition: Front.h:144
Interface to define the fitness calculation of the instances evolved by EIG.
Definition: InstanceFitness.h:17
Abstract Mutation interface.
Definition: Mutation.h:21
Class to represent the Novelty Search Algorithm.
Definition: NoveltySearch.h:50
static double randDouble()
Generates a random double value between 0.0 and 1.0.
Definition: PseudoRandom.cpp:31
Replacement skeleton operator.
Definition: Replacement.h:16
Abstract Selection interface.
Definition: Selection.h:21