Some bugfixing in MO optimization and added empty check: target in tutorial
This commit is contained in:
parent
2dd807ecbe
commit
548b2ae528
4 changed files with 21 additions and 133 deletions
|
|
@ -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,63 +57,14 @@ 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())
|
|
||||||
{ // fresh start
|
|
||||||
setup(_pop);
|
setup(_pop);
|
||||||
return;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Removes the domination info for a given individual, thus nothing dominates it and it dominates nothing.
|
Removes the domination info for a given individual, thus nothing dominates it and it dominates nothing.
|
||||||
|
|
@ -147,21 +93,17 @@ 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[](i)[j] = true;
|
||||||
operator[](j)[i] = false;
|
operator[](j)[i] = false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case b_dominates_a :
|
else if (_pop[j].fitness() > _pop[i].fitness())
|
||||||
{
|
{
|
||||||
operator[](i)[j] = false;
|
operator[](i)[j] = false;
|
||||||
operator[](j)[i] = true;
|
operator[](j)[i] = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default :
|
else
|
||||||
{
|
{
|
||||||
operator[](i)[j] = false;
|
operator[](i)[j] = false;
|
||||||
operator[](j)[i] = false;
|
operator[](j)[i] = false;
|
||||||
|
|
@ -169,7 +111,6 @@ class eoDominanceMap : public eoUF<const eoPop<EoType>&, void>, public std::vect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
For all elements, returns the no. of elements that dominate the element
|
For all elements, returns the no. of elements that dominate the element
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Reference in a new issue