From 548b2ae5284abf14905b15bf831e5310f80f3781 Mon Sep 17 00:00:00 2001 From: maartenkeijzer Date: Fri, 16 Mar 2001 13:11:32 +0000 Subject: [PATCH] Some bugfixing in MO optimization and added empty check: target in tutorial --- eo/src/eoDominanceMap.h | 143 ++++----------------------------------- eo/src/eoParetoFitness.h | 3 +- eo/test/t-eoPareto.cpp | 6 +- eo/tutorial/Makefile | 2 + 4 files changed, 21 insertions(+), 133 deletions(-) diff --git a/eo/src/eoDominanceMap.h b/eo/src/eoDominanceMap.h index aec4a4151..d19e57555 100644 --- a/eo/src/eoDominanceMap.h +++ b/eo/src/eoDominanceMap.h @@ -47,11 +47,6 @@ template class eoDominanceMap : public eoUF&, void>, public std::vector > { public : - /** - Ctor that needs to know what objectives are supposed to be maximized and which are to be minimized. - optional argument, a tolerance. This designates within which tolerance objective values are considered to be equal - */ - eoDominanceMap(const std::vector& _maximizes, double _tol = 1e-6) : maximizes(_maximizes), tol(_tol) {} /** Clears the map @@ -62,62 +57,13 @@ class eoDominanceMap : public eoUF&, void>, public std::vect fitnesses.clear(); } - bool maximize(unsigned objective) const { return maximizes[objective]; } - /** Update or create the dominance map */ void operator()(const eoPop& _pop) { - if (fitness.size() != _pop.size()) - { // fresh start - setup(_pop); - return; - } - // else just update the guys that have changed - - update(_pop); - } - - /// update the map with the population - void update(const eoPop& _pop) - { - for (unsigned i = 0; i < _pop.size(); ++i) - { - if (fitness[i] == _pop[i].fitness()) - { - continue; - } - // it's a new guy, update rows and columns - fitness[i] = _pop[i].fitness(); - - for (unsigned j = 0; j < _pop.size(); ++j) - { - if (i == j) - continue; - - switch (dominates(_pop[i].fitness(), _pop[j].fitness())) - { - case a_dominates_b : - { - operator[](i)[j] = true; - operator[](j)[i] = false; - break; - } - case b_dominates_a : - { - operator[](i)[j] = false; - operator[](j)[i] = true; - break; - } - default : - { - operator[](i)[j] = false; - operator[](j)[i] = false; - } - } - } - } + setup(_pop); + return; } /** @@ -147,25 +93,20 @@ class eoDominanceMap : public eoUF&, void>, public std::vect for (unsigned j = 0; j < i; ++j) { - switch(dominates(fitness[i], fitness[j])) + if (_pop[i].fitness() > _pop[j].fitness()) { - case a_dominates_b : - { - operator[](i)[j] = true; - operator[](j)[i] = false; - break; - } - case b_dominates_a : - { - operator[](i)[j] = false; - operator[](j)[i] = true; - break; - } - default : - { - operator[](i)[j] = false; - operator[](j)[i] = false; - } + operator[](i)[j] = true; + operator[](j)[i] = false; + } + else if (_pop[j].fitness() > _pop[i].fitness()) + { + operator[](i)[j] = false; + operator[](j)[i] = true; + } + else + { + operator[](i)[j] = false; + operator[](j)[i] = false; } } } @@ -215,63 +156,9 @@ class eoDominanceMap : public eoUF&, void>, public std::vect return result; } - /** - make a distinction between no domination (a better than b on one objective and worse on another) - and equality: a == b - */ - enum dom_res {a_dominates_b, b_dominates_a, no_domination, a_equals_b}; - - /** - a dominates b if it is better in one objective and not worse in any of the others - */ - dom_res dominates(typename EoType::Fitness a, typename EoType::Fitness b) - { - dom_res result = a_equals_b; - - for (unsigned i = 0; i < a.size(); ++i) - { - double aval = a[i]; - double bval = b[i]; - - if (!maximizes[i]) - { - aval = -aval; - bval = -bval; - } - - // check if unequal, in the case they're 'equal' just go to the next - if (fabs(aval - bval) > tol) - { - if (aval > bval) - { - if (result == b_dominates_a) - { - return no_domination; // when on another objective b dominated a, they do not dominate each other - } - // else continue comparing - - result = a_dominates_b; - } - else // bval > aval - { - if (result == a_dominates_b) - { - return no_domination; // done - } - - result = b_dominates_a; - } - } - } - - return result; - } - private : - vector maximizes; - double tol; vector fitness; }; diff --git a/eo/src/eoParetoFitness.h b/eo/src/eoParetoFitness.h index 164593e65..4e4b210b0 100644 --- a/eo/src/eoParetoFitness.h +++ b/eo/src/eoParetoFitness.h @@ -62,6 +62,7 @@ public : bool operator<(const eoParetoFitness& _other) const { bool smaller = false; + double tol = FitnessTraits::tol(); const vector& performance = *this; const vector& otherperformance = _other; @@ -70,7 +71,7 @@ public : { bool maxim = FitnessTraits::maximizing(i); double aval = maxim? performance[i] : -performance[i]; - double bval = maxim? otherperformance[i] : otherperformance[i]; + double bval = maxim? otherperformance[i] : -otherperformance[i]; if (fabs(aval - bval) > tol) { diff --git a/eo/test/t-eoPareto.cpp b/eo/test/t-eoPareto.cpp index db944cbea..8aa8c05d3 100644 --- a/eo/test/t-eoPareto.cpp +++ b/eo/test/t-eoPareto.cpp @@ -7,6 +7,7 @@ using namespace std; +// Look: overloading the maximization without overhead (thing can be inlined) class MinimizingFitnessTraits : public eoParetoFitnessTraits { public : @@ -88,10 +89,7 @@ void the_main() unsigned pop_size = 100; eoPop pop(pop_size, init); - vector maximizes(2, false); // minimize both objectives - - // The dominance map needs to know how to compare - eoDominanceMap dominance(maximizes); + eoDominanceMap dominance; // Pareto ranking needs a dominance map //eoParetoRanking perf2worth(dominance); diff --git a/eo/tutorial/Makefile b/eo/tutorial/Makefile index ce7779180..bd3418cb9 100644 --- a/eo/tutorial/Makefile +++ b/eo/tutorial/Makefile @@ -17,5 +17,7 @@ dist : distdir : +check : + clean: for i in $(SUBDIRS); do pushd $$i && $(MAKE) clean; popd; done