12 #ifndef DIGNEA_NSGA2_H
13 #define DIGNEA_NSGA2_H
16 #include <dignea/core/Crossover.h>
17 #include <dignea/core/Mutation.h>
18 #include <dignea/core/Solution.h>
21 #include <dignea/utilities/random/PseudoRandom.h>
55 virtual ~
NSGA2() =
default;
62 return "Non-dominated Sorting Genetic Algorithm II";
69 string getID()
const override {
return "NSGA-II"; }
73 void setProblem(shared_ptr<
Problem<S>> prob)
override;
80 void initProgress()
override;
82 void updateProgress()
override;
84 virtual void createInitialPopulation()
override;
86 virtual void evaluatePopulation(vector<S> &pop)
override;
88 virtual vector<S> createMating()
override;
90 virtual void reproduction(S &, S &)
override;
93 void rankPopulation();
94 vector<S> rankCrowdingPopulation(vector<S> &combinedPopulation);
113 this->population.resize(this->populationSize);
114 for (
int i = 0; i < this->getPopulationSize(); i++) {
115 this->population[i] = this->problem->createSolution();
118 this->evaluatePopulation(this->population);
121 this->nextCheckpoint = 0;
122 this->updateEvolution(0, this->population);
123 this->initProgress();
136 this->performedEvaluations = this->populationSize;
155 this->createInitialPopulation();
156 this->startTime = chrono::system_clock::now();
157 this->rankPopulation();
158 while (!this->isStoppingConditionReached()) {
159 vector offspring = this->createMating();
161 offspring.insert(offspring.end(), this->population.begin(),
162 this->population.end());
163 this->population = this->rankCrowdingPopulation(offspring);
164 this->updateEvolution(this->performedEvaluations, this->population);
166 this->endTime = chrono::system_clock::now();
167 this->finishProgress();
169 throw std::runtime_error(
"Problem is not set in GA::run");
180 vector<vector<S>> fronts =
182 this->population.clear();
183 for (vector<S> front : fronts) {
184 for (S solution : front) {
185 this->population.push_back(solution);
203 vector<vector<S>> fronts =
205 vector<S> newPopulation;
206 newPopulation.reserve(this->populationSize);
207 auto toInsert = this->populationSize;
211 std::for_each(fronts.begin(), fronts.end(),
212 [&](vector<S> &f) { crowOrder(f, this->problem.get()); });
214 bool fits = toInsert <= (int)fronts[0].size();
216 for (S solution : fronts[index]) {
217 newPopulation.push_back(solution);
224 if ((toInsert <= 0) || (toInsert <= (int)fronts[index].size())) {
232 vector<vector<S>> remaining(fronts.begin() + index, fronts.end());
233 auto jv = std::ranges::join_view(remaining);
234 std::ranges::for_each(
235 jv | std::ranges::views::take(toInsert),
236 [&](
const S &solution) { newPopulation.push_back(solution); });
238 return newPopulation;
250 this->evaluator->evaluate(pop, this->problem.get());
265 for (
int i = 0; i < this->populationSize; i++) {
266 S child1 = this->selection->select(this->population);
267 S child2 = this->selection->select(this->population);
268 reproduction(child1, child2);
269 this->problem->evaluate(child1);
270 this->problem->evaluate(child2);
271 offspring.push_back(child1);
272 offspring.push_back(child2);
273 this->performedEvaluations += 2;
290 this->crossover->run(child1, child2);
292 this->mutation->run(child1, this->mutationRate, this->problem.get());
293 this->mutation->run(child2, this->mutationRate, this->problem.get());
303 this->performedEvaluations += 2;
315 if (prob->getNumberOfObjs() != 2) {
316 std::string where =
"NSGA2 setProblem";
317 throw(NoMOAllowed(where));
319 this->problem = prob;
331 std::string where =
"NSGA2 setProblem";
332 throw(NoMOAllowed(where));
334 this->problem.reset(prob);
346 std::ranges::for_each(this->population, [&](
const S &solution) {
vector< vector< S > > fastNonDominatedSort(vector< S > &population, const Problem< S > *problem)
Fast Non Dominated Sorting operator. Sorts the population in different fronts Used in NSGA-II.
Definition: Sorter.h:158
Class to represent an Abstract Genetic Algorithm. Base skeleton is defined here, to extend in particu...
Definition: AbstractGA.h:38
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
void updateProgress() override
Updates the performed evaluations to the population size on each call.
Definition: NSGA2.h:302
NSGA2()
Creates a RAW instance of a Generational GA algorithm.
Definition: NSGA2.h:103
void initProgress() override
Starts the evolutionary process. By default this methods sets the number of performed evaluations to ...
Definition: NSGA2.h:135
virtual Front< S > getResults() const
Creates the front of solution from the evolution.
Definition: NSGA2.h:344
virtual void createInitialPopulation() override
Creates the initial population of individuals before starting the evolutionary process.
Definition: NSGA2.h:112
void run() override
Runs the evolutionary process. This is the main EA method. This methods is in charge of:
Definition: NSGA2.h:153
void setProblem(shared_ptr< Problem< S >> prob) override
Uptades the problem to solve using a share_ptr. The problem must be multi-objective.
Definition: NSGA2.h:314
virtual void reproduction(S &, S &) override
Applies the genetic operator. This methods is invoked from createMating.
Definition: NSGA2.h:287
virtual vector< S > createMating() override
Generates the mating population of individuals to be evaluated. The individuals are selected and afte...
Definition: NSGA2.h:262
string getID() const override
Get the ID of the algorithm.
Definition: NSGA2.h:69
string getName() const override
Get the Name.
Definition: NSGA2.h:61
virtual void evaluatePopulation(vector< S > &pop) override
Evaluates the entire population of individuals using the problem evaluation function.
Definition: NSGA2.h:249
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