3#include "SelRandomOp.h"
14 selRandomOp =
static_cast<SelectionOperatorP
> (
new SelRandomOp);
16 selWorstOp =
static_cast<SelectionOperatorP
> (
new SelWorstOp);
17 this->parentPop =
new std::vector <IndividualP>();
18 this->fronts = boost::shared_ptr<std::vector <std::vector <IndividualP> > > (
new std::vector <std::vector <IndividualP> >());
26 selRandomOp->initialize(state);
27 selWorstOp->initialize(state);
33void AlgNSGA2::quickSort(std::vector <IndividualP> *group,
int left,
int right, std::string prop,
int objective = -1)
35 int i = left, j = right;
38 MOFitnessP pivotMO = boost::static_pointer_cast<MOFitness> (group->at((left + right) / 2)->fitness);
39 double pivot = pivotMO->getProperty(prop, objective);
43 MOFitnessP moFitnessI = boost::static_pointer_cast<MOFitness> (group->at(i)->fitness);
44 while (moFitnessI->getProperty(prop, objective) < pivot) {
46 moFitnessI = boost::static_pointer_cast<MOFitness> (group->at(i)->fitness);
48 MOFitnessP moFitnessJ = boost::static_pointer_cast<MOFitness> (group->at(j)->fitness);
49 while (pivot < moFitnessJ->getProperty(prop, objective)) {
51 moFitnessJ = boost::static_pointer_cast<MOFitness> (group->at(j)->fitness);
56 group->at(i) = group->at(j);
65 quickSort(group, left, j, prop, objective);
67 quickSort(group, i, right, prop, objective);
71void AlgNSGA2::sortBasedOnProperty(std::vector <IndividualP>* deme,
double* fMin,
double* fMax, std::string prop,
int objective = -1)
74 int right = deme->size()-1;
75 quickSort(deme, left, right, prop, objective);
77 MOFitnessP fitness = boost::static_pointer_cast<MOFitness> (deme->at(left)->fitness);
78 *fMin = fitness->getProperty(prop, objective);
79 fitness = boost::static_pointer_cast<MOFitness> (deme->at(right)->fitness);
80 *fMax = fitness->getProperty(prop, objective);
84int AlgNSGA2::checkDominance(MOFitnessP fitness1, MOFitnessP fitness2)
87 uint size = fitness1->size();
88 if (size != fitness2->size()) {
92 for (uint i = 0; i<size; i++) {
93 FitnessP f1 = fitness1->at(i);
94 FitnessP f2 = fitness2->at(i);
95 if (fabs(f1->getValue() - f2->getValue()) > DBL_EPSILON) {
97 if (f1->isBetterThan(f2)) {
102 }
else if (dominance == -1) {
103 if (f1->isBetterThan(f2)) {
109 if (f1->isBetterThan(f2)) {
124void AlgNSGA2::nonDomSorting(boost::shared_ptr<std::vector <IndividualP> > pool,
int N, boost::shared_ptr<std::vector <std::vector <IndividualP> > > fronts)
127 std::vector <IndividualP> Q = *(
new std::vector <IndividualP>());
128 int collectedSoFar = 0;
134 for (uint i = 0; i < pool->size(); i++) {
135 IndividualP ind = pool->at(i);
136 MOFitnessP fitnessI = boost::static_pointer_cast<MOFitness> (ind->fitness);
140 fitnessI->Sp =
new std::vector<IndividualP>();
144 for (uint j = i+1; j < pool->size(); j++) {
145 IndividualP other = pool->at(j);
146 MOFitnessP fitnessJ = boost::static_pointer_cast<MOFitness> (other->fitness);
150 fitnessJ->Sp =
new std::vector<IndividualP>();
154 int dominance = checkDominance(fitnessI, fitnessJ);
155 if (dominance == -1) {
156 fitnessI->Sp->push_back(other);
158 }
else if (dominance == 1) {
160 fitnessJ->Sp->push_back(ind);
166 if (fitnessI->nc == 0) {
176 while (Q.size() != 0) {
177 fronts->push_back(Q);
184 std::vector <IndividualP> newQ;
185 for (uint i=0; i<Q.size(); i++) {
187 MOFitnessP fitnessI = boost::static_pointer_cast<MOFitness> (Q.at(i)->fitness);
189 for (uint j=0; j<fitnessI->Sp->size(); j++) {
191 IndividualP dominated = fitnessI->Sp->at(j);
192 MOFitnessP fitnessJ = boost::static_pointer_cast<MOFitness> (dominated->fitness);
194 if (fitnessJ->nc == 0) {
196 newQ.push_back(dominated);
208void AlgNSGA2::crowdedDistanceEst(StateP state, std::vector <IndividualP> *deme)
210 MOFitnessP fitness = boost::static_pointer_cast<MOFitness> (deme->at(0)->fitness);
211 uint objCount = fitness->size();
212 for (uint i = 0; i<objCount; i++) {
220 sortBasedOnProperty(deme, &fMin, &fMax,
"objective", i);
224 for (uint j = 0; j<deme->size(); j++) {
225 fitness = boost::static_pointer_cast<MOFitness> (deme->at(j)->fitness);
231 fitness->crowding_distance = 0;
236 if (j == 0 || j == deme->size()-1) {
239 increment = fMax - fMin;
246 MOFitnessP fitnessNeighbour = boost::static_pointer_cast<MOFitness> (deme->at(j+1)->fitness);
247 increment = fitnessNeighbour->getValueOfObjective(i);
250 fitnessNeighbour = boost::static_pointer_cast<MOFitness> (deme->at(j-1)->fitness);
251 increment -= fitnessNeighbour->getValueOfObjective(i);
256 increment /= fMax - fMin;
257 fitness->crowding_distance += increment;
270void AlgNSGA2::makeNewPop(StateP state, DemeP deme)
272 for(uint iIter = 0; iIter < deme->size(); iIter++) {
274 ECF_LOG(state, 5,
"Individuals in tournament: ");
276 std::vector<IndividualP> tournament = *(
new std::vector<IndividualP>());
277 for (uint i = 0; i < 2; ++i) {
279 tournament.push_back(selRandomOp->select(*deme));
280 ECF_LOG(state, 5, uint2str(i) +
": " + tournament[i]->toString());
284 IndividualP worst = selWorstOp->select(tournament);
285 ECF_LOG(state, 5,
"The worst from the tournament: " + worst->toString());
290 IndividualP myMate = selRandomOp->select(*deme);
293 mate(tournament[0], myMate, worst);
300 ECF_LOG(state, 5,
"New individual: " + worst->toString());
307 static bool firstGen =
true;
311 this->makeNewPop(state, deme);
314 uint N = deme->size();
315 bool initialGeneration = parentPop->size() == 0;
316 for (uint
id = 0;
id<parentPop->size();
id++) {
317 deme->push_back((IndividualP) parentPop->at(
id)->copy());
323 nonDomSorting(deme, N, fronts);
329 while (size + fronts->at(i).size() <= N) {
330 crowdedDistanceEst(state, &(fronts->at(i)));
331 for (uint j = 0; j<fronts->at(i).size(); j++) {
332 deme->push_back(fronts->at(i).at(j));
334 size += fronts->at(i).size();
338 if (!initialGeneration) {
341 crowdedDistanceEst(state, &(fronts->at(i)));
342 sortBasedOnProperty(&(fronts->at(i)), &fMin, &fMax,
"crowding_distance");
344 int howMany = N - deme->size();
345 int lastFrontSize = fronts->at(i).size();
346 for (
int j = lastFrontSize-1; j >= (lastFrontSize - howMany); j--) {
347 deme->push_back(fronts->at(i).at(j));
376 for (uint i = 0; i<deme->size(); i++) {
377 this->parentPop->push_back((IndividualP) deme->at(i)->copy());
bool advanceGeneration(StateP state, DemeP deme)
Perform a single generation on a single deme.
bool initialize(StateP state)
Initialize the algorithm, read parameters from the system, do a sanity check.
uint mutate(const std::vector< IndividualP > &pool)
Helper function: send a vector of individuals to mutation.
std::string name_
algorithm name
bool mate(IndividualP p1, IndividualP p2, IndividualP child)
Helper function: crossover two individuals.
bool removeFrom(IndividualP victim, std::vector< IndividualP > &pool)
Helper function: remove victim from pool of individual pointers.
void evaluate(IndividualP ind)
Helper function: evaluate an individual.
Random individual selection operator.
Worst individual selection operator.