paradiseo/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h

162 lines
5.5 KiB
C++

/*
(c) 2013 Thales group
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; version 2
of the License.
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: http://eodev.sourceforge.net
Authors:
Johann Dréo <johann.dreo@thalesgroup.com>
*/
#ifndef MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_
#define MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_
#include <fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h>
template<class MOEOT>
class moeoExpBinaryIndicatorBasedDualFitnessAssignment : public moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>
{
protected:
eoDualPopSplit<MOEOT> _pop_split;
public:
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
typedef typename ObjectiveVector::Type Type;
using moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>::values;
moeoExpBinaryIndicatorBasedDualFitnessAssignment(
moeoNormalizedSolutionVsSolutionBinaryMetric<ObjectiveVector,double> & metric,
const double kappa = 0.05
) : moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>( metric, kappa ) {}
/*! If the population is homogeneous (only composed of feasible individuals or unfeasible ones),
* then apply the operators on the whole population.
* But, if there is at least one feasible individual, then apply them only on the feasible individuals.
*/
virtual void operator()( eoPop<MOEOT>& pop )
{
// separate the pop in feasible/unfeasible
_pop_split( pop );
eoPop<MOEOT>* ppop;
// if there is at least one feasible individual,
// it will supersede all the unfeasible ones
if( _pop_split.feasible().size() == 0 ) {
ppop = & _pop_split.unfeasible();
} else {
ppop = & _pop_split.feasible();
}
this->setup(*ppop);
this->computeValues(*ppop);
this->setFitnesses(*ppop); // NOTE: this alter individuals
// bring back altered individuals in the pop
pop = _pop_split.merge();
}
protected:
using moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>::kappa;
using moeoExpBinaryIndicatorBasedFitnessAssignment<MOEOT>::metric;
/**
* Sets the bounds for every objective using the min and the max value for every objective vector of _pop
* @param _pop the population
*/
void setup(const eoPop < MOEOT > & _pop)
{
Type worst, best;
typename MOEOT::ObjectiveVector::Type::Compare cmp;
for (unsigned int i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
{
worst = _pop[0].objectiveVector()[i];
best = _pop[0].objectiveVector()[i];
for (unsigned int j=1; j<_pop.size(); j++)
{
// use the overloaded comparison operators
worst = std::min(worst, _pop[j].objectiveVector()[i], cmp );
best = std::max(best, _pop[j].objectiveVector()[i], cmp );
}
// Get real min/max
double min = std::min(worst.value(), best.value());
double max = std::max(worst.value(), best.value());
// Build a fitness with them
assert( best.is_feasible() == worst.is_feasible() ); // we are supposed to work on homogeneous pop
Type fmin( min, best.is_feasible() );
Type fmax( max, best.is_feasible() );
// setting of the bounds for the objective i
metric.setup( fmin, fmax, i);
}
}
/**
* Compute every indicator value in values (values[i] = I(_v[i], _o))
* @param _pop the population
*/
virtual void computeValues(const eoPop < MOEOT > & pop)
{
values.clear();
values.resize(pop.size());
for (unsigned int i=0; i<pop.size(); i++) {
values[i].resize(pop.size());
// the metric may not be symetric, thus neither is the matrix
for (unsigned int j=0; j<pop.size(); j++) {
if (i != j) {
values[i][j] = Type(
metric( pop[i].objectiveVector(), pop[j].objectiveVector() ),
pop[i].objectiveVector().is_feasible()
);
} // if i != j
} // for j in pop
} // for i in pop
}
virtual void setFitnesses(eoPop < MOEOT > & pop)
{
for (unsigned int i=0; i<pop.size(); i++) {
// We should maintain the feasibility of the fitness across computations
pop[i].fitness( this->computeFitness(i), pop[i].fitness().is_feasible() );
}
}
virtual Type computeFitness(const unsigned int _idx)
{
Type result( 0.0, values[_idx][_idx].is_feasible() );
for (unsigned int i=0; i<values.size(); i++)
{
if (i != _idx)
{
result -= exp(-values[i][_idx]/kappa);
}
}
return result;
}
};
#endif // MOEOEXPBINARYINDICATORBASEDDUALFITNESSASSIGNMENT_H_