Some bugfixing in MO optimization and added empty check: target in tutorial

This commit is contained in:
maartenkeijzer 2001-03-16 13:11:32 +00:00
commit 548b2ae528
4 changed files with 21 additions and 133 deletions

View file

@ -47,11 +47,6 @@ template <class EoType>
class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vector<std::vector<bool> > class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vector<std::vector<bool> >
{ {
public : 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<bool>& _maximizes, double _tol = 1e-6) : maximizes(_maximizes), tol(_tol) {}
/** /**
Clears the map Clears the map
@ -62,62 +57,13 @@ class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vect
fitnesses.clear(); fitnesses.clear();
} }
bool maximize(unsigned objective) const { return maximizes[objective]; }
/** /**
Update or create the dominance map Update or create the dominance map
*/ */
void operator()(const eoPop<EoType>& _pop) void operator()(const eoPop<EoType>& _pop)
{ {
if (fitness.size() != _pop.size()) setup(_pop);
{ // fresh start return;
setup(_pop);
return;
}
// else just update the guys that have changed
update(_pop);
}
/// update the map with the population
void update(const eoPop<EoType>& _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;
}
}
}
}
} }
/** /**
@ -147,25 +93,20 @@ class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vect
for (unsigned j = 0; j < i; ++j) 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;
operator[](i)[j] = true; }
operator[](j)[i] = false; else if (_pop[j].fitness() > _pop[i].fitness())
break; {
} operator[](i)[j] = false;
case b_dominates_a : operator[](j)[i] = true;
{ }
operator[](i)[j] = false; else
operator[](j)[i] = true; {
break; operator[](i)[j] = false;
} operator[](j)[i] = false;
default :
{
operator[](i)[j] = false;
operator[](j)[i] = false;
}
} }
} }
} }
@ -215,63 +156,9 @@ class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vect
return result; 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 : private :
vector<bool> maximizes;
double tol;
vector<typename EoType::Fitness> fitness; vector<typename EoType::Fitness> fitness;
}; };

View file

@ -62,6 +62,7 @@ public :
bool operator<(const eoParetoFitness<FitnessTraits>& _other) const bool operator<(const eoParetoFitness<FitnessTraits>& _other) const
{ {
bool smaller = false; bool smaller = false;
double tol = FitnessTraits::tol(); double tol = FitnessTraits::tol();
const vector<double>& performance = *this; const vector<double>& performance = *this;
const vector<double>& otherperformance = _other; const vector<double>& otherperformance = _other;
@ -70,7 +71,7 @@ public :
{ {
bool maxim = FitnessTraits::maximizing(i); bool maxim = FitnessTraits::maximizing(i);
double aval = maxim? performance[i] : -performance[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) if (fabs(aval - bval) > tol)
{ {

View file

@ -7,6 +7,7 @@
using namespace std; using namespace std;
// Look: overloading the maximization without overhead (thing can be inlined)
class MinimizingFitnessTraits : public eoParetoFitnessTraits class MinimizingFitnessTraits : public eoParetoFitnessTraits
{ {
public : public :
@ -88,10 +89,7 @@ void the_main()
unsigned pop_size = 100; unsigned pop_size = 100;
eoPop<eoDouble> pop(pop_size, init); eoPop<eoDouble> pop(pop_size, init);
vector<bool> maximizes(2, false); // minimize both objectives eoDominanceMap<eoDouble> dominance;
// The dominance map needs to know how to compare
eoDominanceMap<eoDouble> dominance(maximizes);
// Pareto ranking needs a dominance map // Pareto ranking needs a dominance map
//eoParetoRanking<eoDouble> perf2worth(dominance); //eoParetoRanking<eoDouble> perf2worth(dominance);

View file

@ -17,5 +17,7 @@ dist :
distdir : distdir :
check :
clean: clean:
for i in $(SUBDIRS); do pushd $$i && $(MAKE) clean; popd; done for i in $(SUBDIRS); do pushd $$i && $(MAKE) clean; popd; done