Adding class eoParetoOneConstraintFitness, multi-valued fitness + 1 constraint
This file shoudl contain the general Pareto+contraint class - but I'm in a big hurry.
This commit is contained in:
parent
194f6bf45e
commit
8f740ab884
1 changed files with 229 additions and 0 deletions
229
eo/src/eoParetoConstraintFitness.h
Normal file
229
eo/src/eoParetoConstraintFitness.h
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// eoParetoConstraintFitness.h
|
||||
// (c) Maarten Keijzer and Marc Schoenauer, 2001
|
||||
/*
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Contact: mkeijzer@cs.vu.nl
|
||||
Marc.Schoenauer@inria.fr
|
||||
*/
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _eoParetoConstraintFitness_h
|
||||
#define _eoParetoConstraintFitness_h
|
||||
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
eoParetoOneConstraintFitness class:
|
||||
std::vector of doubles + constraint value
|
||||
|
||||
Comparison (dominance) is done
|
||||
on pareto dominance for 2 feasible individuals,
|
||||
one feasible individual always wins over an infeasible
|
||||
on constraint violations for 2 infeasible individuals
|
||||
|
||||
The template argument FitnessTraits defaults to
|
||||
eoParetoFitnessTraits, which can be replaces at will by any other
|
||||
class that implements the static functions defined therein.
|
||||
|
||||
Note that the domninance defines a partial order, so that
|
||||
!dominates(a,b) && !domaintes(b,a) does not neccessarily imply that (a==b)
|
||||
The other way around does hold.
|
||||
|
||||
However, be careful that the comparison operators do define a total order
|
||||
based on considering first objective, then in case of tie, second objective, etc
|
||||
|
||||
NOTE: in a hurry, I did not want to make it derive from eoParetoFitness
|
||||
(used cut-and-paste instead!) : I know it might be a good idea, but I'm
|
||||
not sure I see why at the moment (any hint someone?)
|
||||
*/
|
||||
template <class FitnessTraits = eoParetoFitnessTraits>
|
||||
class eoParetoOneConstraintFitness : public std::vector<double>
|
||||
{
|
||||
private:
|
||||
// this class implements only 1 inequality constraint
|
||||
// (must ponder a bit for generality without huge overload)
|
||||
double constraintValue; // inequality cstr - must be negative
|
||||
|
||||
public :
|
||||
typedef FitnessTraits fitness_traits;
|
||||
|
||||
eoParetoOneConstraintFitness(void) : std::vector<double>(FitnessTraits::nObjectives(),0.0) {}
|
||||
|
||||
// Ctr from a vector<double> (size nObjectives+1)
|
||||
eoParetoOneConstraintFitness(std::vector<double> & _v) :
|
||||
std::vector<double>(_v)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (_v.size() != fitness_traits::nObjectives()+1)
|
||||
throw runtime_error("Size error in Ctor of eoParetoOneConstraintFitness from vector");
|
||||
#endif
|
||||
constraintValue = _v[fitness_traits::nObjectives()];
|
||||
resize(fitness_traits::nObjectives());
|
||||
}
|
||||
|
||||
// Ctr from a vector<double> and a value
|
||||
eoParetoOneConstraintFitness(std::vector<double> & _v, double _c) :
|
||||
std::vector<double>(_v), constraintValue(_c)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (_v.size() != fitness_traits::nObjectives())
|
||||
throw runtime_error("Size error in Ctor of eoParetoOneConstraintFitness from vector and value");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** access to the traits characteristics (so you don't have to write
|
||||
* a lot of typedef's around
|
||||
*/
|
||||
static void setUp(unsigned _n, std::vector<bool> & _b) {FitnessTraits::setUp(_n, _b);}
|
||||
static bool maximizing(unsigned _i) { return FitnessTraits::maximizing(_i);}
|
||||
|
||||
bool feasible() const { return constraintValue<=0;}
|
||||
double violation() const { return (feasible()?0.0:constraintValue);}
|
||||
double ConstraintValue() const {return constraintValue;}
|
||||
void ConstraintValue(double _c) {constraintValue=_c;}
|
||||
|
||||
/// Partial order based on Pareto-dominance
|
||||
//bool operator<(const eoParetoFitness<FitnessTraits>& _other) const
|
||||
bool dominates(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
|
||||
{
|
||||
bool dom = false;
|
||||
|
||||
double tol = FitnessTraits::tol();
|
||||
const std::vector<double>& performance = *this;
|
||||
const std::vector<double>& otherperformance = _other;
|
||||
|
||||
if (feasible() && _other.feasible())
|
||||
// here both are feasible: do the "standard" domination
|
||||
for (unsigned i = 0; i < FitnessTraits::nObjectives(); ++i)
|
||||
{
|
||||
bool maxim = FitnessTraits::maximizing(i);
|
||||
double aval = maxim? performance[i] : -performance[i];
|
||||
double bval = maxim? otherperformance[i] : -otherperformance[i];
|
||||
|
||||
if (fabs(aval - bval) > tol)
|
||||
{
|
||||
if (aval < bval)
|
||||
{
|
||||
return false; // cannot dominate
|
||||
}
|
||||
// else aval < bval
|
||||
dom = true; // for the moment: goto next objective
|
||||
}
|
||||
//else they're equal in this objective, goto next
|
||||
}
|
||||
else
|
||||
{ // one at least is not feasible
|
||||
if (feasible())
|
||||
return true; // feasible wins
|
||||
else if (_other.feasible())
|
||||
return false; // feasible wins
|
||||
return (violation()<_other.violation()); // smallest violation wins
|
||||
}
|
||||
|
||||
return dom;
|
||||
}
|
||||
|
||||
/// compare *not* on dominance, but on the first, then the second, etc
|
||||
bool operator<(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
|
||||
{
|
||||
double tol = FitnessTraits::tol();
|
||||
const std::vector<double>& performance = *this;
|
||||
const std::vector<double>& otherperformance = _other;
|
||||
for (unsigned i = 0; i < FitnessTraits::nObjectives(); ++i)
|
||||
{
|
||||
bool maxim = FitnessTraits::maximizing(i);
|
||||
double aval = maxim? performance[i] : -performance[i];
|
||||
double bval = maxim? otherperformance[i] : -otherperformance[i];
|
||||
|
||||
if (fabs(aval-bval) > tol)
|
||||
{
|
||||
if (aval < bval)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator>(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
|
||||
{
|
||||
return _other < *this;
|
||||
}
|
||||
|
||||
bool operator<=(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
|
||||
{
|
||||
return operator==(_other) || operator<(_other);
|
||||
}
|
||||
|
||||
bool operator>=(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
|
||||
{
|
||||
return _other <= *this;
|
||||
}
|
||||
|
||||
bool operator==(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
|
||||
{ // check if they're all within tolerance
|
||||
for (unsigned i = 0; i < size(); ++i)
|
||||
{
|
||||
if (fabs(operator[](i) - _other[i]) > FitnessTraits::tol())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const eoParetoOneConstraintFitness<FitnessTraits>& _other) const
|
||||
{ return ! operator==(_other); }
|
||||
|
||||
};
|
||||
|
||||
template <class FitnessTraits>
|
||||
std::ostream& operator<<(std::ostream& os, const eoParetoOneConstraintFitness<FitnessTraits>& fitness)
|
||||
{
|
||||
for (unsigned i = 0; i < fitness.size(); ++i)
|
||||
{
|
||||
os << fitness[i] << ' ';
|
||||
}
|
||||
os << fitness.ConstraintValue() << " " ;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class FitnessTraits>
|
||||
std::istream& operator>>(std::istream& is, eoParetoOneConstraintFitness<FitnessTraits>& fitness)
|
||||
{
|
||||
fitness = eoParetoOneConstraintFitness<FitnessTraits>();
|
||||
for (unsigned i = 0; i < fitness.size(); ++i)
|
||||
{
|
||||
is >> fitness[i];
|
||||
}
|
||||
double r;
|
||||
is >> r;
|
||||
fitness.ConstraintValue(r);
|
||||
return is;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in a new issue