indent all

git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@232 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
liefooga 2007-04-13 15:05:07 +00:00
commit c8049ca6cd
51 changed files with 3899 additions and 3898 deletions

View file

@ -24,264 +24,264 @@
* The template argument MOEOFitness is an object reflecting the quality of the solution in term of convergence (the fitness of a solution is always to be maximized).
* The template argument MOEODiversity is an object reflecting the quality of the solution in term of diversity (the diversity of a solution is always to be maximized).
* All template arguments must have a void and a copy constructor.
* Besides, note that, contrary to the mono-objective case (and to EO) where the fitness value of a solution is confused with its objective value,
* Besides, note that, contrary to the mono-objective case (and to EO) where the fitness value of a solution is confused with its objective value,
* the fitness value differs of the objectives values in the multi-objective case.
*/
template < class MOEOObjectiveVector, class MOEOFitness, class MOEODiversity >
template < class MOEOObjectiveVector, class MOEOFitness, class MOEODiversity >
class MOEO : public EO < MOEOObjectiveVector >
{
public:
/** the objective vector type of a solution */
typedef MOEOObjectiveVector ObjectiveVector;
/** the fitness type of a solution */
typedef MOEOFitness Fitness;
/** the diversity type of a solution */
typedef MOEODiversity Diversity;
/**
* Ctor
*/
MOEO()
{
// default values for every parameters
objectiveVectorValue = ObjectiveVector();
fitnessValue = Fitness();
diversityValue = Diversity();
// invalidate all
invalidate();
}
/**
* Virtual dtor
*/
virtual ~MOEO() {};
/**
* Returns the objective vector of the current solution
*/
ObjectiveVector objectiveVector() const
{
if ( invalidObjectiveVector() )
{
throw std::runtime_error("invalid objective vector");
}
return objectiveVectorValue;
}
/**
* Sets the objective vector of the current solution
* @param _objectiveVectorValue the new objective vector
*/
void objectiveVector(const ObjectiveVector & _objectiveVectorValue)
{
objectiveVectorValue = _objectiveVectorValue;
invalidObjectiveVectorValue = false;
}
/**
* Sets the objective vector as invalid
*/
void invalidateObjectiveVector()
{
invalidObjectiveVectorValue = true;
}
/**
* Returns true if the objective vector is invalid, false otherwise
*/
bool invalidObjectiveVector() const
{
return invalidObjectiveVectorValue;
}
/**
* Returns the fitness value of the current solution
*/
Fitness fitness() const
{
if ( invalidFitness() )
{
throw std::runtime_error("invalid fitness (MOEO)");
}
return fitnessValue;
}
/**
* Sets the fitness value of the current solution
* @param _fitnessValue the new fitness value
*/
void fitness(const Fitness & _fitnessValue)
{
fitnessValue = _fitnessValue;
invalidFitnessValue = false;
}
/**
* Sets the fitness value as invalid
*/
void invalidateFitness()
{
invalidFitnessValue = true;
}
/**
* Returns true if the fitness value is invalid, false otherwise
*/
bool invalidFitness() const
{
return invalidFitnessValue;
}
/**
* Returns the diversity value of the current solution
*/
Diversity diversity() const
{
if ( invalidDiversity() )
{
throw std::runtime_error("invalid diversity");
}
return diversityValue;
}
/**
* Sets the diversity value of the current solution
* @param _diversityValue the new diversity value
*/
void diversity(const Diversity & _diversityValue)
{
diversityValue = _diversityValue;
invalidDiversityValue = false;
}
/**
* Sets the diversity value as invalid
*/
void invalidateDiversity()
{
invalidDiversityValue = true;
}
/**
* Returns true if the diversity value is invalid, false otherwise
*/
bool invalidDiversity() const
{
return invalidDiversityValue;
}
/**
* Sets the objective vector, the fitness value and the diversity value as invalid
*/
void invalidate()
{
invalidateObjectiveVector();
invalidateFitness();
invalidateDiversity();
}
/**
* Returns true if the fitness value is invalid, false otherwise
*/
bool invalid() const
{
return invalidObjectiveVector();
}
/**
* Returns true if the objective vector of the current solution is smaller than the objective vector of _other on the first objective,
* then on the second, and so on (can be usefull for sorting/printing).
* You should implement another function in the sub-class of MOEO to have another sorting mecanism.
* @param _other the other MOEO object to compare with
*/
bool operator<(const MOEO & _other) const
{
return objectiveVector() < _other.objectiveVector();
}
/**
* Return the class id (the class name as a std::string)
*/
virtual std::string className() const
{
return "MOEO";
}
/**
* Writing object
* @param _os output stream
*/
virtual void printOn(std::ostream & _os) const
{
if ( invalidObjectiveVector() )
{
_os << "INVALID\t";
}
else
{
_os << objectiveVectorValue << '\t';
}
}
/**
* Reading object
* @param _is input stream
*/
virtual void readFrom(std::istream & _is)
{
std::string objectiveVector_str;
int pos = _is.tellg();
_is >> objectiveVector_str;
if (objectiveVector_str == "INVALID")
{
invalidateObjectiveVector();
}
else
{
invalidObjectiveVectorValue = false;
_is.seekg(pos); // rewind
_is >> objectiveVectorValue;
}
}
/** the objective vector type of a solution */
typedef MOEOObjectiveVector ObjectiveVector;
/** the fitness type of a solution */
typedef MOEOFitness Fitness;
/** the diversity type of a solution */
typedef MOEODiversity Diversity;
/**
* Ctor
*/
MOEO()
{
// default values for every parameters
objectiveVectorValue = ObjectiveVector();
fitnessValue = Fitness();
diversityValue = Diversity();
// invalidate all
invalidate();
}
/**
* Virtual dtor
*/
virtual ~MOEO() {};
/**
* Returns the objective vector of the current solution
*/
ObjectiveVector objectiveVector() const
{
if ( invalidObjectiveVector() )
{
throw std::runtime_error("invalid objective vector");
}
return objectiveVectorValue;
}
/**
* Sets the objective vector of the current solution
* @param _objectiveVectorValue the new objective vector
*/
void objectiveVector(const ObjectiveVector & _objectiveVectorValue)
{
objectiveVectorValue = _objectiveVectorValue;
invalidObjectiveVectorValue = false;
}
/**
* Sets the objective vector as invalid
*/
void invalidateObjectiveVector()
{
invalidObjectiveVectorValue = true;
}
/**
* Returns true if the objective vector is invalid, false otherwise
*/
bool invalidObjectiveVector() const
{
return invalidObjectiveVectorValue;
}
/**
* Returns the fitness value of the current solution
*/
Fitness fitness() const
{
if ( invalidFitness() )
{
throw std::runtime_error("invalid fitness (MOEO)");
}
return fitnessValue;
}
/**
* Sets the fitness value of the current solution
* @param _fitnessValue the new fitness value
*/
void fitness(const Fitness & _fitnessValue)
{
fitnessValue = _fitnessValue;
invalidFitnessValue = false;
}
/**
* Sets the fitness value as invalid
*/
void invalidateFitness()
{
invalidFitnessValue = true;
}
/**
* Returns true if the fitness value is invalid, false otherwise
*/
bool invalidFitness() const
{
return invalidFitnessValue;
}
/**
* Returns the diversity value of the current solution
*/
Diversity diversity() const
{
if ( invalidDiversity() )
{
throw std::runtime_error("invalid diversity");
}
return diversityValue;
}
/**
* Sets the diversity value of the current solution
* @param _diversityValue the new diversity value
*/
void diversity(const Diversity & _diversityValue)
{
diversityValue = _diversityValue;
invalidDiversityValue = false;
}
/**
* Sets the diversity value as invalid
*/
void invalidateDiversity()
{
invalidDiversityValue = true;
}
/**
* Returns true if the diversity value is invalid, false otherwise
*/
bool invalidDiversity() const
{
return invalidDiversityValue;
}
/**
* Sets the objective vector, the fitness value and the diversity value as invalid
*/
void invalidate()
{
invalidateObjectiveVector();
invalidateFitness();
invalidateDiversity();
}
/**
* Returns true if the fitness value is invalid, false otherwise
*/
bool invalid() const
{
return invalidObjectiveVector();
}
/**
* Returns true if the objective vector of the current solution is smaller than the objective vector of _other on the first objective,
* then on the second, and so on (can be usefull for sorting/printing).
* You should implement another function in the sub-class of MOEO to have another sorting mecanism.
* @param _other the other MOEO object to compare with
*/
bool operator<(const MOEO & _other) const
{
return objectiveVector() < _other.objectiveVector();
}
/**
* Return the class id (the class name as a std::string)
*/
virtual std::string className() const
{
return "MOEO";
}
/**
* Writing object
* @param _os output stream
*/
virtual void printOn(std::ostream & _os) const
{
if ( invalidObjectiveVector() )
{
_os << "INVALID\t";
}
else
{
_os << objectiveVectorValue << '\t';
}
}
/**
* Reading object
* @param _is input stream
*/
virtual void readFrom(std::istream & _is)
{
std::string objectiveVector_str;
int pos = _is.tellg();
_is >> objectiveVector_str;
if (objectiveVector_str == "INVALID")
{
invalidateObjectiveVector();
}
else
{
invalidObjectiveVectorValue = false;
_is.seekg(pos); // rewind
_is >> objectiveVectorValue;
}
}
private:
/** the objective vector of this solution */
ObjectiveVector objectiveVectorValue;
/** true if the objective vector is invalid */
bool invalidObjectiveVectorValue;
/** the fitness value of this solution */
Fitness fitnessValue;
/** true if the fitness value is invalid */
bool invalidFitnessValue;
/** the diversity value of this solution */
Diversity diversityValue;
/** true if the diversity value is invalid */
bool invalidDiversityValue;
/** the objective vector of this solution */
ObjectiveVector objectiveVectorValue;
/** true if the objective vector is invalid */
bool invalidObjectiveVectorValue;
/** the fitness value of this solution */
Fitness fitnessValue;
/** true if the fitness value is invalid */
bool invalidFitnessValue;
/** the diversity value of this solution */
Diversity diversityValue;
/** true if the diversity value is invalid */
bool invalidDiversityValue;
};

View file

@ -43,7 +43,7 @@ eoCheckPoint < MOEOT > & do_make_checkpoint_moeo (eoParser & _parser, eoState &
{
eoCheckPoint < MOEOT > & checkpoint = _state.storeFunctor(new eoCheckPoint < MOEOT > (_continue));
/* the objective vector type */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
// get number of obectives
unsigned nObj = ObjectiveVector::nObjectives();
@ -63,17 +63,17 @@ eoCheckPoint < MOEOT > & do_make_checkpoint_moeo (eoParser & _parser, eoState &
// shoudl we empty it if exists
eoValueParam<bool>& eraseParam = _parser.getORcreateParam(true, "eraseDir", "erase files in dirName if any", '\0', "Output");
bool dirOK = false; // not tested yet
// Dump of the whole population
//-----------------------------
bool printPop = _parser.getORcreateParam(false, "printPop", "Print sorted pop. every gen.", '\0', "Output").value();
eoSortedPopStat<MOEOT> * popStat;
if ( printPop ) // we do want pop dump
{
popStat = & _state.storeFunctor(new eoSortedPopStat<MOEOT>);
checkpoint.add(*popStat);
popStat = & _state.storeFunctor(new eoSortedPopStat<MOEOT>);
checkpoint.add(*popStat);
}
//////////////////////////////////
// State savers
//////////////////////////////
@ -82,36 +82,36 @@ eoCheckPoint < MOEOT > & do_make_checkpoint_moeo (eoParser & _parser, eoState &
eoValueParam<unsigned>& saveFrequencyParam = _parser.createParam(unsigned(0), "saveFrequency", "Save every F generation (0 = only final state, absent = never)", '\0', "Persistence" );
if (_parser.isItThere(saveFrequencyParam))
{
// first make sure dirName is OK
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX );
// first make sure dirName is OK
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
unsigned freq = (saveFrequencyParam.value()>0 ? saveFrequencyParam.value() : UINT_MAX );
#ifdef _MSVC
std::string stmp = dirName + "\generations";
std::string stmp = dirName + "\generations";
#else
std::string stmp = dirName + "/generations";
std::string stmp = dirName + "/generations";
#endif
eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp);
_state.storeFunctor(stateSaver1);
checkpoint.add(*stateSaver1);
eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp);
_state.storeFunctor(stateSaver1);
checkpoint.add(*stateSaver1);
}
// save state every T seconds
eoValueParam<unsigned>& saveTimeIntervalParam = _parser.getORcreateParam(unsigned(0), "saveTimeInterval", "Save every T seconds (0 or absent = never)", '\0',"Persistence" );
if (_parser.isItThere(saveTimeIntervalParam) && saveTimeIntervalParam.value()>0)
{
// first make sure dirName is OK
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
// first make sure dirName is OK
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
#ifdef _MSVC
std::string stmp = dirName + "\time";
std::string stmp = dirName + "\time";
#else
std::string stmp = dirName + "/time";
std::string stmp = dirName + "/time";
#endif
eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp);
_state.storeFunctor(stateSaver2);
checkpoint.add(*stateSaver2);
eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp);
_state.storeFunctor(stateSaver2);
checkpoint.add(*stateSaver2);
}
///////////////////
// Archive
//////////////////
@ -119,58 +119,58 @@ eoCheckPoint < MOEOT > & do_make_checkpoint_moeo (eoParser & _parser, eoState &
bool updateArch = _parser.getORcreateParam(true, "updateArch", "Update the archive at each gen.", '\0', "Evolution Engine").value();
if (updateArch)
{
moeoArchiveUpdater < MOEOT > * updater = new moeoArchiveUpdater < MOEOT > (_archive, _pop);
_state.storeFunctor(updater);
checkpoint.add(*updater);
moeoArchiveUpdater < MOEOT > * updater = new moeoArchiveUpdater < MOEOT > (_archive, _pop);
_state.storeFunctor(updater);
checkpoint.add(*updater);
}
// store the objective vectors contained in the archive every generation
bool storeArch = _parser.getORcreateParam(false, "storeArch", "Store the archive's objective vectors at each gen.", '\0', "Output").value();
if (storeArch)
{
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
#ifdef _MSVC
std::string stmp = dirName + "\arch";
std::string stmp = dirName + "\arch";
#else
std::string stmp = dirName + "/arch";
std::string stmp = dirName + "/arch";
#endif
moeoArchiveObjectiveVectorSavingUpdater < MOEOT > * save_updater = new moeoArchiveObjectiveVectorSavingUpdater < MOEOT > (_archive, stmp);
_state.storeFunctor(save_updater);
checkpoint.add(*save_updater);
moeoArchiveObjectiveVectorSavingUpdater < MOEOT > * save_updater = new moeoArchiveObjectiveVectorSavingUpdater < MOEOT > (_archive, stmp);
_state.storeFunctor(save_updater);
checkpoint.add(*save_updater);
}
// store the contribution of the non-dominated solutions
bool cont = _parser.getORcreateParam(false, "contribution", "Store the contribution of the archive at each gen.", '\0', "Output").value();
if (cont)
{
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
#ifdef _MSVC
std::string stmp = dirName + "\contribution";
std::string stmp = dirName + "\contribution";
#else
std::string stmp = dirName + "/contribution";
std::string stmp = dirName + "/contribution";
#endif
moeoContributionMetric < ObjectiveVector > * contribution = new moeoContributionMetric < ObjectiveVector >;
moeoBinaryMetricSavingUpdater < MOEOT > * contribution_updater = new moeoBinaryMetricSavingUpdater < MOEOT > (*contribution, _archive, stmp);
_state.storeFunctor(contribution_updater);
checkpoint.add(*contribution_updater);
moeoContributionMetric < ObjectiveVector > * contribution = new moeoContributionMetric < ObjectiveVector >;
moeoBinaryMetricSavingUpdater < MOEOT > * contribution_updater = new moeoBinaryMetricSavingUpdater < MOEOT > (*contribution, _archive, stmp);
_state.storeFunctor(contribution_updater);
checkpoint.add(*contribution_updater);
}
// store the entropy of the non-dominated solutions
bool ent = _parser.getORcreateParam(false, "entropy", "Store the entropy of the archive at each gen.", '\0', "Output").value();
if (ent)
{
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
if (! dirOK )
dirOK = testDirRes(dirName, eraseParam.value()); // TRUE
#ifdef _MSVC
std::string stmp = dirName + "\entropy";
std::string stmp = dirName + "\entropy";
#else
std::string stmp = dirName + "/entropy";
std::string stmp = dirName + "/entropy";
#endif
moeoEntropyMetric < ObjectiveVector > * entropy = new moeoEntropyMetric < ObjectiveVector >;
moeoBinaryMetricSavingUpdater < MOEOT > * entropy_updater = new moeoBinaryMetricSavingUpdater < MOEOT > (*entropy, _archive, stmp);
_state.storeFunctor(entropy_updater);
checkpoint.add(*entropy_updater);
moeoEntropyMetric < ObjectiveVector > * entropy = new moeoEntropyMetric < ObjectiveVector >;
moeoBinaryMetricSavingUpdater < MOEOT > * entropy_updater = new moeoBinaryMetricSavingUpdater < MOEOT > (*entropy, _archive, stmp);
_state.storeFunctor(entropy_updater);
checkpoint.add(*entropy_updater);
}
// and that's it for the (control and) output
return checkpoint;
}

View file

@ -19,7 +19,7 @@
#include <eoFitContinue.h>
#include <eoTimeContinue.h>
#ifndef _MSC_VER
#include <eoCtrlCContinue.h>
#include <eoCtrlCContinue.h>
#endif
#include <utils/eoParser.h>
#include <utils/eoState.h>
@ -33,11 +33,11 @@
template <class MOEOT>
eoCombinedContinue<MOEOT> * make_combinedContinue(eoCombinedContinue<MOEOT> *_combined, eoContinue<MOEOT> *_cont)
{
if (_combined) // already exists
_combined->add(*_cont);
else
_combined = new eoCombinedContinue<MOEOT>(*_cont);
return _combined;
if (_combined) // already exists
_combined->add(*_cont);
else
_combined = new eoCombinedContinue<MOEOT>(*_cont);
return _combined;
}
@ -50,56 +50,56 @@ eoCombinedContinue<MOEOT> * make_combinedContinue(eoCombinedContinue<MOEOT> *_co
template <class MOEOT>
eoContinue<MOEOT> & do_make_continue_moeo(eoParser& _parser, eoState& _state, eoEvalFuncCounter<MOEOT> & _eval)
{
// the combined continue - to be filled
eoCombinedContinue<MOEOT> *continuator = NULL;
// First the eoGenContinue - need a default value so you can run blind
// but we also need to be able to avoid it <--> 0
eoValueParam<unsigned>& maxGenParam = _parser.createParam(unsigned(100), "maxGen", "Maximum number of generations (0 = none)",'G',"Stopping criterion");
if (maxGenParam.value()) // positive: -> define and store
{
eoGenContinue<MOEOT> *genCont = new eoGenContinue<MOEOT>(maxGenParam.value());
_state.storeFunctor(genCont);
// and "add" to combined
continuator = make_combinedContinue<MOEOT>(continuator, genCont);
}
// maxEval
eoValueParam<unsigned long>& maxEvalParam = _parser.getORcreateParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)", 'E', "Stopping criterion");
if (maxEvalParam.value())
{
eoEvalContinue<MOEOT> *evalCont = new eoEvalContinue<MOEOT>(_eval, maxEvalParam.value());
_state.storeFunctor(evalCont);
// and "add" to combined
continuator = make_combinedContinue<MOEOT>(continuator, evalCont);
}
// maxTime
eoValueParam<unsigned long>& maxTimeParam = _parser.getORcreateParam((unsigned long)0, "maxTime", "Maximum running time in seconds (0 = none)", 'T', "Stopping criterion");
if (maxTimeParam.value()) // positive: -> define and store
{
eoTimeContinue<MOEOT> *timeCont = new eoTimeContinue<MOEOT>(maxTimeParam.value());
_state.storeFunctor(timeCont);
// and "add" to combined
continuator = make_combinedContinue<MOEOT>(continuator, timeCont);
}
// CtrlC
// the combined continue - to be filled
eoCombinedContinue<MOEOT> *continuator = NULL;
// First the eoGenContinue - need a default value so you can run blind
// but we also need to be able to avoid it <--> 0
eoValueParam<unsigned>& maxGenParam = _parser.createParam(unsigned(100), "maxGen", "Maximum number of generations (0 = none)",'G',"Stopping criterion");
if (maxGenParam.value()) // positive: -> define and store
{
eoGenContinue<MOEOT> *genCont = new eoGenContinue<MOEOT>(maxGenParam.value());
_state.storeFunctor(genCont);
// and "add" to combined
continuator = make_combinedContinue<MOEOT>(continuator, genCont);
}
// maxEval
eoValueParam<unsigned long>& maxEvalParam = _parser.getORcreateParam((unsigned long)0, "maxEval", "Maximum number of evaluations (0 = none)", 'E', "Stopping criterion");
if (maxEvalParam.value())
{
eoEvalContinue<MOEOT> *evalCont = new eoEvalContinue<MOEOT>(_eval, maxEvalParam.value());
_state.storeFunctor(evalCont);
// and "add" to combined
continuator = make_combinedContinue<MOEOT>(continuator, evalCont);
}
// maxTime
eoValueParam<unsigned long>& maxTimeParam = _parser.getORcreateParam((unsigned long)0, "maxTime", "Maximum running time in seconds (0 = none)", 'T', "Stopping criterion");
if (maxTimeParam.value()) // positive: -> define and store
{
eoTimeContinue<MOEOT> *timeCont = new eoTimeContinue<MOEOT>(maxTimeParam.value());
_state.storeFunctor(timeCont);
// and "add" to combined
continuator = make_combinedContinue<MOEOT>(continuator, timeCont);
}
// CtrlC
#ifndef _MSC_VER
// the CtrlC interception (Linux only I'm afraid)
eoCtrlCContinue<MOEOT> *ctrlCCont;
eoValueParam<bool>& ctrlCParam = _parser.createParam(true, "CtrlC", "Terminate current generation upon Ctrl C",'C', "Stopping criterion");
if (_parser.isItThere(ctrlCParam))
{
ctrlCCont = new eoCtrlCContinue<MOEOT>;
// store
_state.storeFunctor(ctrlCCont);
// add to combinedContinue
continuator = make_combinedContinue<MOEOT>(continuator, ctrlCCont);
}
{
ctrlCCont = new eoCtrlCContinue<MOEOT>;
// store
_state.storeFunctor(ctrlCCont);
// add to combinedContinue
continuator = make_combinedContinue<MOEOT>(continuator, ctrlCCont);
}
#endif
// now check that there is at least one!
if (!continuator)
throw std::runtime_error("You MUST provide a stopping criterion");
// OK, it's there: store in the eoState
_state.storeFunctor(continuator);
// and return
throw std::runtime_error("You MUST provide a stopping criterion");
// OK, it's there: store in the eoState
_state.storeFunctor(continuator);
// and return
return *continuator;
}

View file

@ -53,189 +53,189 @@
template < class MOEOT >
moeoEA < MOEOT > & do_make_ea_moeo(eoParser & _parser, eoState & _state, eoEvalFunc < MOEOT > & _eval, eoContinue < MOEOT > & _continue, eoGenOp < MOEOT > & _op, moeoArchive < MOEOT > & _archive)
{
/* the objective vector type */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/* the objective vector type */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/* the fitness assignment strategy */
string & fitnessParam = _parser.createParam(string("FastNonDominatedSorting"), "fitness",
"Fitness assignment scheme: Dummy, FastNonDominatedSorting or IndicatorBased", 'F',
"Evolution Engine").value();
string & indicatorParam = _parser.createParam(string("Epsilon"), "indicator",
"Binary indicator for IndicatorBased: Epsilon, Hypervolume", 'i',
"Evolution Engine").value();
double rho = _parser.createParam(1.1, "rho", "reference point for the hypervolume indicator", 'r',
"Evolution Engine").value();
double kappa = _parser.createParam(0.05, "kappa", "Scaling factor kappa for IndicatorBased", 'k',
"Evolution Engine").value();
moeoFitnessAssignment < MOEOT > * fitnessAssignment;
if (fitnessParam == string("Dummy"))
{
fitnessAssignment = new moeoDummyFitnessAssignment < MOEOT> ();
}
else if (fitnessParam == string("FastNonDominatedSorting"))
{
fitnessAssignment = new moeoFastNonDominatedSortingFitnessAssignment < MOEOT> ();
}
else if (fitnessParam == string("IndicatorBased"))
{
// metric
moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > *metric;
if (indicatorParam == string("Epsilon"))
{
metric = new moeoAdditiveEpsilonBinaryMetric < ObjectiveVector >;
}
else if (indicatorParam == string("Hypervolume"))
{
metric = new moeoHypervolumeBinaryMetric < ObjectiveVector > (rho);
}
else
{
string stmp = string("Invalid binary quality indicator: ") + indicatorParam;
throw std::runtime_error(stmp.c_str());
}
fitnessAssignment = new moeoIndicatorBasedFitnessAssignment < MOEOT> (metric, kappa);
}
/* the fitness assignment strategy */
string & fitnessParam = _parser.createParam(string("FastNonDominatedSorting"), "fitness",
"Fitness assignment scheme: Dummy, FastNonDominatedSorting or IndicatorBased", 'F',
"Evolution Engine").value();
string & indicatorParam = _parser.createParam(string("Epsilon"), "indicator",
"Binary indicator for IndicatorBased: Epsilon, Hypervolume", 'i',
"Evolution Engine").value();
double rho = _parser.createParam(1.1, "rho", "reference point for the hypervolume indicator", 'r',
"Evolution Engine").value();
double kappa = _parser.createParam(0.05, "kappa", "Scaling factor kappa for IndicatorBased", 'k',
"Evolution Engine").value();
moeoFitnessAssignment < MOEOT > * fitnessAssignment;
if (fitnessParam == string("Dummy"))
{
fitnessAssignment = new moeoDummyFitnessAssignment < MOEOT> ();
}
else if (fitnessParam == string("FastNonDominatedSorting"))
{
fitnessAssignment = new moeoFastNonDominatedSortingFitnessAssignment < MOEOT> ();
}
else if (fitnessParam == string("IndicatorBased"))
{
// metric
moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > *metric;
if (indicatorParam == string("Epsilon"))
{
metric = new moeoAdditiveEpsilonBinaryMetric < ObjectiveVector >;
}
else if (indicatorParam == string("Hypervolume"))
{
metric = new moeoHypervolumeBinaryMetric < ObjectiveVector > (rho);
}
else
{
string stmp = string("Invalid binary quality indicator: ") + indicatorParam;
throw std::runtime_error(stmp.c_str());
}
fitnessAssignment = new moeoIndicatorBasedFitnessAssignment < MOEOT> (metric, kappa);
}
else
{
string stmp = string("Invalid fitness assignment strategy: ") + fitnessParam;
throw std::runtime_error(stmp.c_str());
string stmp = string("Invalid fitness assignment strategy: ") + fitnessParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(fitnessAssignment);
/* the diversity assignment strategy */
string & diversityParam = _parser.createParam(string("Dummy"), "diversity",
"Diversity assignment scheme: Dummy or CrowdingDistance", 'D', "Evolution Engine").value();
moeoDiversityAssignment < MOEOT > * diversityAssignment;
if (diversityParam == string("CrowdingDistance"))
{
diversityAssignment = new moeoCrowdingDistanceDiversityAssignment < MOEOT> ();
}
else if (diversityParam == string("Dummy"))
{
diversityAssignment = new moeoDummyDiversityAssignment < MOEOT> ();
}
/* the diversity assignment strategy */
string & diversityParam = _parser.createParam(string("Dummy"), "diversity",
"Diversity assignment scheme: Dummy or CrowdingDistance", 'D', "Evolution Engine").value();
moeoDiversityAssignment < MOEOT > * diversityAssignment;
if (diversityParam == string("CrowdingDistance"))
{
diversityAssignment = new moeoCrowdingDistanceDiversityAssignment < MOEOT> ();
}
else if (diversityParam == string("Dummy"))
{
diversityAssignment = new moeoDummyDiversityAssignment < MOEOT> ();
}
else
{
string stmp = string("Invalid diversity assignment strategy: ") + diversityParam;
throw std::runtime_error(stmp.c_str());
string stmp = string("Invalid diversity assignment strategy: ") + diversityParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(diversityAssignment);
/* the comparator strategy */
string & comparatorParam = _parser.createParam(string("FitnessThenDiversity"), "comparator",
"Comparator scheme: FitnessThenDiversity or DiversityThenFitness", 'C', "Evolution Engine").value();
moeoComparator < MOEOT > * comparator;
if (comparatorParam == string("FitnessThenDiversity"))
{
comparator = new moeoFitnessThenDiversityComparator < MOEOT> ();
}
else if (comparatorParam == string("DiversityThenFitness"))
{
comparator = new moeoDiversityThenFitnessComparator < MOEOT> ();
}
string & comparatorParam = _parser.createParam(string("FitnessThenDiversity"), "comparator",
"Comparator scheme: FitnessThenDiversity or DiversityThenFitness", 'C', "Evolution Engine").value();
moeoComparator < MOEOT > * comparator;
if (comparatorParam == string("FitnessThenDiversity"))
{
comparator = new moeoFitnessThenDiversityComparator < MOEOT> ();
}
else if (comparatorParam == string("DiversityThenFitness"))
{
comparator = new moeoDiversityThenFitnessComparator < MOEOT> ();
}
else
{
string stmp = string("Invalid comparator strategy: ") + comparatorParam;
throw std::runtime_error(stmp.c_str());
string stmp = string("Invalid comparator strategy: ") + comparatorParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(comparator);
/* the selection strategy */
eoValueParam < eoParamParamType > & selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection",
"Selection scheme: DetTour(T), StochTour(t) or Random", 'S', "Evolution Engine");
eoParamParamType & ppSelect = selectionParam.value();
moeoSelectOne < MOEOT > * select;
if (ppSelect.first == string("DetTour"))
{
unsigned tSize;
if (!ppSelect.second.size()) // no parameter added
{
cerr << "WARNING, no parameter passed to DetTour, using 2" << endl;
tSize = 2;
// put back 2 in parameter for consistency (and status file)
ppSelect.second.push_back(string("2"));
}
else // parameter passed by user as DetTour(T)
{
tSize = atoi(ppSelect.second[0].c_str());
}
select = new moeoDetTournamentSelect < MOEOT > (*comparator, tSize);
}
else if (ppSelect.first == string("StochTour"))
{
double tRate;
if (!ppSelect.second.size()) // no parameter added
{
cerr << "WARNING, no parameter passed to StochTour, using 1" << endl;
tRate = 1;
// put back 1 in parameter for consistency (and status file)
ppSelect.second.push_back(string("1"));
}
else // parameter passed by user as StochTour(T)
{
tRate = atof(ppSelect.second[0].c_str());
}
select = new moeoStochTournamentSelect < MOEOT > (*comparator, tRate);
}
else if (ppSelect.first == string("Roulette"))
{
// TO DO !
// ...
}
else if (ppSelect.first == string("Random"))
{
select = new moeoRandomSelect <MOEOT > ();
}
else
{
string stmp = string("Invalid selection strategy: ") + ppSelect.first;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(select);
/* the replacement strategy */
string & replacementParam = _parser.createParam(string("Elitist"), "replacement",
"Replacement scheme: Elitist, Environmental or Generational", 'R', "Evolution Engine").value();
moeoReplacement < MOEOT > * replace;
if (replacementParam == string("Elitist"))
{
replace = new moeoElitistReplacement < MOEOT> (*fitnessAssignment, *diversityAssignment, *comparator);
}
else if (replacementParam == string("Environmental"))
{
replace = new moeoEnvironmentalReplacement < MOEOT> (*fitnessAssignment, *diversityAssignment, *comparator);
}
else if (replacementParam == string("Generational"))
{
replace = new moeoGenerationalReplacement < MOEOT> ();
}
eoValueParam < eoParamParamType > & selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection",
"Selection scheme: DetTour(T), StochTour(t) or Random", 'S', "Evolution Engine");
eoParamParamType & ppSelect = selectionParam.value();
moeoSelectOne < MOEOT > * select;
if (ppSelect.first == string("DetTour"))
{
unsigned tSize;
if (!ppSelect.second.size()) // no parameter added
{
cerr << "WARNING, no parameter passed to DetTour, using 2" << endl;
tSize = 2;
// put back 2 in parameter for consistency (and status file)
ppSelect.second.push_back(string("2"));
}
else // parameter passed by user as DetTour(T)
{
tSize = atoi(ppSelect.second[0].c_str());
}
select = new moeoDetTournamentSelect < MOEOT > (*comparator, tSize);
}
else if (ppSelect.first == string("StochTour"))
{
double tRate;
if (!ppSelect.second.size()) // no parameter added
{
cerr << "WARNING, no parameter passed to StochTour, using 1" << endl;
tRate = 1;
// put back 1 in parameter for consistency (and status file)
ppSelect.second.push_back(string("1"));
}
else // parameter passed by user as StochTour(T)
{
tRate = atof(ppSelect.second[0].c_str());
}
select = new moeoStochTournamentSelect < MOEOT > (*comparator, tRate);
}
else if (ppSelect.first == string("Roulette"))
{
// TO DO !
// ...
}
else if (ppSelect.first == string("Random"))
{
select = new moeoRandomSelect <MOEOT > ();
}
else
{
string stmp = string("Invalid replacement strategy: ") + replacementParam;
throw std::runtime_error(stmp.c_str());
string stmp = string("Invalid selection strategy: ") + ppSelect.first;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(select);
/* the replacement strategy */
string & replacementParam = _parser.createParam(string("Elitist"), "replacement",
"Replacement scheme: Elitist, Environmental or Generational", 'R', "Evolution Engine").value();
moeoReplacement < MOEOT > * replace;
if (replacementParam == string("Elitist"))
{
replace = new moeoElitistReplacement < MOEOT> (*fitnessAssignment, *diversityAssignment, *comparator);
}
else if (replacementParam == string("Environmental"))
{
replace = new moeoEnvironmentalReplacement < MOEOT> (*fitnessAssignment, *diversityAssignment, *comparator);
}
else if (replacementParam == string("Generational"))
{
replace = new moeoGenerationalReplacement < MOEOT> ();
}
else
{
string stmp = string("Invalid replacement strategy: ") + replacementParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(replace);
/* the number of offspring */
eoValueParam < eoHowMany > & offspringRateParam = _parser.createParam(eoHowMany(1.0), "nbOffspring",
"Number of offspring (percentage or absolute)", 'O', "Evolution Engine");
// the general breeder
eoGeneralBreeder < MOEOT > * breed = new eoGeneralBreeder < MOEOT > (*select, _op, offspringRateParam.value());
_state.storeFunctor(breed);
// the eoEasyEA
moeoEA < MOEOT > * algo = new moeoEasyEA < MOEOT > (_continue, _eval, *breed, *replace, *fitnessAssignment, *diversityAssignment);
_state.storeFunctor(algo);
return *algo;
/* the number of offspring */
eoValueParam < eoHowMany > & offspringRateParam = _parser.createParam(eoHowMany(1.0), "nbOffspring",
"Number of offspring (percentage or absolute)", 'O', "Evolution Engine");
// the general breeder
eoGeneralBreeder < MOEOT > * breed = new eoGeneralBreeder < MOEOT > (*select, _op, offspringRateParam.value());
_state.storeFunctor(breed);
// the eoEasyEA
moeoEA < MOEOT > * algo = new moeoEasyEA < MOEOT > (_continue, _eval, *breed, *replace, *fitnessAssignment, *diversityAssignment);
_state.storeFunctor(algo);
return *algo;
}
#endif /*MAKE_EA_MOEO_H_*/

View file

@ -41,80 +41,80 @@
*/
template < class MOEOT, class Move >
moeoLS < MOEOT, eoPop<MOEOT> & > & do_make_ls_moeo (
eoParser & _parser,
eoState & _state,
eoEvalFunc < MOEOT > & _eval,
moeoMoveIncrEval < Move > & _moveIncrEval,
eoContinue < MOEOT > & _continue,
eoMonOp < MOEOT > & _op,
eoMonOp < MOEOT > & _opInit,
moMoveInit < Move > & _moveInit,
moNextMove < Move > & _nextMove,
moeoArchive < MOEOT > & _archive
)
eoParser & _parser,
eoState & _state,
eoEvalFunc < MOEOT > & _eval,
moeoMoveIncrEval < Move > & _moveIncrEval,
eoContinue < MOEOT > & _continue,
eoMonOp < MOEOT > & _op,
eoMonOp < MOEOT > & _opInit,
moMoveInit < Move > & _moveInit,
moNextMove < Move > & _nextMove,
moeoArchive < MOEOT > & _archive
)
{
/* the objective vector type */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/* the fitness assignment strategy */
string & fitnessParam = _parser.getORcreateParam(string("IndicatorBased"), "fitness",
"Fitness assignment strategy parameter: IndicatorBased...", 'F',
"Evolution Engine").value();
string & indicatorParam = _parser.getORcreateParam(string("Epsilon"), "indicator",
"Binary indicator to use with the IndicatorBased assignment: Epsilon, Hypervolume", 'i',
"Evolution Engine").value();
double rho = _parser.getORcreateParam(1.1, "rho", "reference point for the hypervolume indicator",
'r', "Evolution Engine").value();
double kappa = _parser.getORcreateParam(0.05, "kappa", "Scaling factor kappa for IndicatorBased",
'k', "Evolution Engine").value();
moeoIndicatorBasedFitnessAssignment < MOEOT > * fitnessAssignment;
if (fitnessParam == string("IndicatorBased"))
{
// metric
moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > *metric;
if (indicatorParam == string("Epsilon"))
{
metric = new moeoAdditiveEpsilonBinaryMetric < ObjectiveVector >;
}
else if (indicatorParam == string("Hypervolume"))
{
metric = new moeoHypervolumeBinaryMetric < ObjectiveVector > (rho);
}
else
{
string stmp = string("Invalid binary quality indicator: ") + indicatorParam;
throw std::runtime_error(stmp.c_str());
}
fitnessAssignment = new moeoIndicatorBasedFitnessAssignment < MOEOT> (metric, kappa);
}
else
{
string stmp = string("Invalid fitness assignment strategy: ") + fitnessParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(fitnessAssignment);
// number of iterations
unsigned n = _parser.getORcreateParam(1, "n", "Number of iterations for population Initialization", 'n', "Evolution Engine").value();
// LS
string & lsParam = _parser.getORcreateParam(string("I-IBMOLS"), "ls",
"Local Search: IBMOLS, I-IBMOLS (Iterated-IBMOLS)...", 'L',
"Evolution Engine").value();
moeoLS < MOEOT, eoPop<MOEOT> & > * ls;
if (lsParam == string("IBMOLS"))
{
ls = new moeoIndicatorBasedLS < MOEOT, Move > (_moveInit, _nextMove, _eval, _moveIncrEval, *fitnessAssignment, _continue);;
}
else if (lsParam == string("I-IBMOLS"))
{
ls = new moeoIteratedIBMOLS < MOEOT, Move > (_moveInit, _nextMove, _eval, _moveIncrEval, *fitnessAssignment, _continue, _op, _opInit, n);
}
else
{
string stmp = string("Invalid fitness assignment strategy: ") + fitnessParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(ls);
// that's it !
return *ls;
/* the objective vector type */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/* the fitness assignment strategy */
string & fitnessParam = _parser.getORcreateParam(string("IndicatorBased"), "fitness",
"Fitness assignment strategy parameter: IndicatorBased...", 'F',
"Evolution Engine").value();
string & indicatorParam = _parser.getORcreateParam(string("Epsilon"), "indicator",
"Binary indicator to use with the IndicatorBased assignment: Epsilon, Hypervolume", 'i',
"Evolution Engine").value();
double rho = _parser.getORcreateParam(1.1, "rho", "reference point for the hypervolume indicator",
'r', "Evolution Engine").value();
double kappa = _parser.getORcreateParam(0.05, "kappa", "Scaling factor kappa for IndicatorBased",
'k', "Evolution Engine").value();
moeoIndicatorBasedFitnessAssignment < MOEOT > * fitnessAssignment;
if (fitnessParam == string("IndicatorBased"))
{
// metric
moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > *metric;
if (indicatorParam == string("Epsilon"))
{
metric = new moeoAdditiveEpsilonBinaryMetric < ObjectiveVector >;
}
else if (indicatorParam == string("Hypervolume"))
{
metric = new moeoHypervolumeBinaryMetric < ObjectiveVector > (rho);
}
else
{
string stmp = string("Invalid binary quality indicator: ") + indicatorParam;
throw std::runtime_error(stmp.c_str());
}
fitnessAssignment = new moeoIndicatorBasedFitnessAssignment < MOEOT> (metric, kappa);
}
else
{
string stmp = string("Invalid fitness assignment strategy: ") + fitnessParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(fitnessAssignment);
// number of iterations
unsigned n = _parser.getORcreateParam(1, "n", "Number of iterations for population Initialization", 'n', "Evolution Engine").value();
// LS
string & lsParam = _parser.getORcreateParam(string("I-IBMOLS"), "ls",
"Local Search: IBMOLS, I-IBMOLS (Iterated-IBMOLS)...", 'L',
"Evolution Engine").value();
moeoLS < MOEOT, eoPop<MOEOT> & > * ls;
if (lsParam == string("IBMOLS"))
{
ls = new moeoIndicatorBasedLS < MOEOT, Move > (_moveInit, _nextMove, _eval, _moveIncrEval, *fitnessAssignment, _continue);;
}
else if (lsParam == string("I-IBMOLS"))
{
ls = new moeoIteratedIBMOLS < MOEOT, Move > (_moveInit, _nextMove, _eval, _moveIncrEval, *fitnessAssignment, _continue, _op, _opInit, n);
}
else
{
string stmp = string("Invalid fitness assignment strategy: ") + fitnessParam;
throw std::runtime_error(stmp.c_str());
}
_state.storeFunctor(ls);
// that's it !
return *ls;
}
#endif /*MAKE_LS_MOEO_H_*/

View file

@ -19,69 +19,69 @@
#include <utils/eoUpdater.h>
#include <metric/moeoMetric.h>
/**
* This class allows to save the progression of a binary metric comparing the objective vectors of the current population (or archive)
* with the objective vectors of the population (or archive) of the generation (n-1) into a file
/**
* This class allows to save the progression of a binary metric comparing the objective vectors of the current population (or archive)
* with the objective vectors of the population (or archive) of the generation (n-1) into a file
*/
template < class MOEOT >
class moeoBinaryMetricSavingUpdater : public eoUpdater
{
{
public:
/**
* The objective vector type of a solution
*/
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Ctor
* @param _metric the binary metric comparing two Pareto sets
* @param _pop the main population
* @param _filename the target filename
*/
moeoBinaryMetricSavingUpdater (moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > & _metric, const eoPop < MOEOT > & _pop, std::string _filename) :
metric(_metric), pop(_pop), filename(_filename), counter(1)
{}
/**
* The objective vector type of a solution
*/
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Saves the metric's value for the current generation
*/
void operator()() {
if (pop.size()) {
if (firstGen) {
firstGen = false;
}
else {
// creation of the two Pareto sets
std::vector < ObjectiveVector > from;
std::vector < ObjectiveVector > to;
for (unsigned i=0; i<pop.size(); i++)
from.push_back(pop[i].objectiveVector());
for (unsigned i=0 ; i<oldPop.size(); i++)
to.push_back(oldPop[i].objectiveVector());
// writing the result into the file
std::ofstream f (filename.c_str(), std::ios::app);
f << counter++ << ' ' << metric(from,to) << std::endl;
f.close();
}
oldPop = pop;
}
}
/**
* Ctor
* @param _metric the binary metric comparing two Pareto sets
* @param _pop the main population
* @param _filename the target filename
*/
moeoBinaryMetricSavingUpdater (moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > & _metric, const eoPop < MOEOT > & _pop, std::string _filename) :
metric(_metric), pop(_pop), filename(_filename), counter(1)
{}
/**
* Saves the metric's value for the current generation
*/
void operator()() {
if (pop.size()) {
if (firstGen) {
firstGen = false;
}
else {
// creation of the two Pareto sets
std::vector < ObjectiveVector > from;
std::vector < ObjectiveVector > to;
for (unsigned i=0; i<pop.size(); i++)
from.push_back(pop[i].objectiveVector());
for (unsigned i=0 ; i<oldPop.size(); i++)
to.push_back(oldPop[i].objectiveVector());
// writing the result into the file
std::ofstream f (filename.c_str(), std::ios::app);
f << counter++ << ' ' << metric(from,to) << std::endl;
f.close();
}
oldPop = pop;
}
}
private:
/** binary metric comparing two Pareto sets */
moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > & metric;
/** main population */
const eoPop < MOEOT > & pop;
/** (n-1) population */
eoPop< MOEOT > oldPop;
/** target filename */
std::string filename;
/** is it the first generation ? */
bool firstGen;
/** counter */
unsigned counter;
/** binary metric comparing two Pareto sets */
moeoVectorVsVectorBinaryMetric < ObjectiveVector, double > & metric;
/** main population */
const eoPop < MOEOT > & pop;
/** (n-1) population */
eoPop< MOEOT > oldPop;
/** target filename */
std::string filename;
/** is it the first generation ? */
bool firstGen;
/** counter */
unsigned counter;
};

View file

@ -24,74 +24,74 @@ class moeoContributionMetric : public moeoVectorVsVectorBinaryMetric < Objective
{
public:
/**
* Returns the contribution of the Pareto set '_set1' relatively to the Pareto set '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned c = card_C(_set1, _set2);
unsigned w1 = card_W(_set1, _set2);
unsigned n1 = card_N(_set1, _set2);
unsigned w2 = card_W(_set2, _set1);
unsigned n2 = card_N(_set2, _set1);
return (double) (c / 2.0 + w1 + n1) / (c + w1 + n1 + w2 + n2);
}
/**
* Returns the contribution of the Pareto set '_set1' relatively to the Pareto set '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned c = card_C(_set1, _set2);
unsigned w1 = card_W(_set1, _set2);
unsigned n1 = card_N(_set1, _set2);
unsigned w2 = card_W(_set2, _set1);
unsigned n2 = card_N(_set2, _set1);
return (double) (c / 2.0 + w1 + n1) / (c + w1 + n1 + w2 + n2);
}
private:
/**
* Returns the number of solutions both in '_set1' and '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_C (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned c=0;
for (unsigned i=0; i<_set1.size(); i++)
for (unsigned j=0; j<_set2.size(); j++)
if (_set1[i] == _set2[j]) {
c++;
break;
}
return c;
}
/**
* Returns the number of solutions both in '_set1' and '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_C (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned c=0;
for (unsigned i=0; i<_set1.size(); i++)
for (unsigned j=0; j<_set2.size(); j++)
if (_set1[i] == _set2[j]) {
c++;
break;
}
return c;
}
/**
* Returns the number of solutions in '_set1' dominating at least one solution of '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_W (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned w=0;
for (unsigned i=0; i<_set1.size(); i++)
for (unsigned j=0; j<_set2.size(); j++)
if (_set1[i].dominates(_set2[j])) {
w++;
break;
}
return w;
}
/**
* Returns the number of solutions in '_set1' dominating at least one solution of '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_W (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned w=0;
for (unsigned i=0; i<_set1.size(); i++)
for (unsigned j=0; j<_set2.size(); j++)
if (_set1[i].dominates(_set2[j])) {
w++;
break;
}
return w;
}
/**
* Returns the number of solutions in '_set1' having no relation of dominance with those from '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_N (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned n=0;
for (unsigned i=0; i<_set1.size(); i++) {
bool domin_rel = false;
for (unsigned j=0; j<_set2.size(); j++)
if (_set1[i].dominates(_set2[j]) || _set2[j].dominates(_set1 [i])) {
domin_rel = true;
break;
}
if (! domin_rel)
n++;
}
return n;
}
/**
* Returns the number of solutions in '_set1' having no relation of dominance with those from '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
unsigned card_N (const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
unsigned n=0;
for (unsigned i=0; i<_set1.size(); i++) {
bool domin_rel = false;
for (unsigned j=0; j<_set2.size(); j++)
if (_set1[i].dominates(_set2[j]) || _set2[j].dominates(_set1 [i])) {
domin_rel = true;
break;
}
if (! domin_rel)
n++;
}
return n;
}
};

View file

@ -24,153 +24,153 @@ class moeoEntropyMetric : public moeoVectorVsVectorBinaryMetric < ObjectiveVecto
{
public:
/**
* Returns the entropy of the Pareto set '_set1' relatively to the Pareto set '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
// normalization
std::vector< ObjectiveVector > set1 = _set1;
std::vector< ObjectiveVector > set2= _set2;
removeDominated (set1);
removeDominated (set2);
prenormalize (set1);
normalize (set1);
normalize (set2);
// making of PO*
std::vector< ObjectiveVector > star; // rotf :-)
computeUnion (set1, set2, star);
removeDominated (star);
// making of PO1 U PO*
std::vector< ObjectiveVector > union_set1_star; // rotf again ...
computeUnion (set1, star, union_set1_star);
unsigned C = union_set1_star.size();
float omega=0;
float entropy=0;
for (unsigned i=0 ; i<C ; i++) {
unsigned N_i = howManyInNicheOf (union_set1_star, union_set1_star[i], star.size());
unsigned n_i = howManyInNicheOf (set1, union_set1_star[i], star.size());
if (n_i > 0) {
omega += 1.0 / N_i;
entropy += (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0));
}
}
entropy /= - log (omega);
entropy *= log (2.0);
return entropy;
}
/**
* Returns the entropy of the Pareto set '_set1' relatively to the Pareto set '_set2'
* @param _set1 the first Pareto set
* @param _set2 the second Pareto set
*/
double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) {
// normalization
std::vector< ObjectiveVector > set1 = _set1;
std::vector< ObjectiveVector > set2= _set2;
removeDominated (set1);
removeDominated (set2);
prenormalize (set1);
normalize (set1);
normalize (set2);
// making of PO*
std::vector< ObjectiveVector > star; // rotf :-)
computeUnion (set1, set2, star);
removeDominated (star);
// making of PO1 U PO*
std::vector< ObjectiveVector > union_set1_star; // rotf again ...
computeUnion (set1, star, union_set1_star);
unsigned C = union_set1_star.size();
float omega=0;
float entropy=0;
for (unsigned i=0 ; i<C ; i++) {
unsigned N_i = howManyInNicheOf (union_set1_star, union_set1_star[i], star.size());
unsigned n_i = howManyInNicheOf (set1, union_set1_star[i], star.size());
if (n_i > 0) {
omega += 1.0 / N_i;
entropy += (float) n_i / (N_i * C) * log (((float) n_i / C) / log (2.0));
}
}
entropy /= - log (omega);
entropy *= log (2.0);
return entropy;
}
private:
/** vector of min values */
std::vector<double> vect_min_val;
/** vector of max values */
std::vector<double> vect_max_val;
/** vector of min values */
std::vector<double> vect_min_val;
/** vector of max values */
std::vector<double> vect_max_val;
/**
* Removes the dominated individuals contained in _f
* @param _f a Pareto set
*/
void removeDominated(std::vector < ObjectiveVector > & _f) {
for (unsigned i=0 ; i<_f.size(); i++) {
bool dom = false;
for (unsigned j=0; j<_f.size(); j++)
if (i != j && _f[j].dominates(_f[i])) {
dom = true;
break;
}
if (dom) {
_f[i] = _f.back();
_f.pop_back();
i--;
}
}
}
/**
* Prenormalization
* @param _f a Pareto set
*/
void prenormalize (const std::vector< ObjectiveVector > & _f) {
vect_min_val.clear();
vect_max_val.clear();
for (unsigned char i=0 ; i<ObjectiveVector::nObjectives(); i++) {
float min_val = _f.front()[i], max_val = min_val;
for (unsigned j=1 ; j<_f.size(); j++) {
if (_f[j][i] < min_val)
min_val = _f[j][i];
if (_f[j][i]>max_val)
max_val = _f[j][i];
}
vect_min_val.push_back(min_val);
vect_max_val.push_back (max_val);
}
}
/**
* Normalization
* @param _f a Pareto set
*/
void normalize (std::vector< ObjectiveVector > & _f) {
for (unsigned i=0 ; i<ObjectiveVector::nObjectives(); i++)
for (unsigned j=0; j<_f.size(); j++)
_f[j][i] = (_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]);
}
/**
* Computation of the union of _f1 and _f2 in _f
* @param _f1 the first Pareto set
* @param _f2 the second Pareto set
* @param _f the final Pareto set
*/
void computeUnion(const std::vector< ObjectiveVector > & _f1, const std::vector< ObjectiveVector > & _f2, std::vector< ObjectiveVector > & _f) {
_f = _f1 ;
for (unsigned i=0; i<_f2.size(); i++) {
bool b = false;
for (unsigned j=0; j<_f1.size(); j ++)
if (_f1[j] == _f2[i]) {
b = true;
break;
}
if (! b)
_f.push_back(_f2[i]);
}
}
/**
* How many in niche
*/
unsigned howManyInNicheOf (const std::vector< ObjectiveVector > & _f, const ObjectiveVector & _s, unsigned _size) {
unsigned n=0;
for (unsigned i=0 ; i<_f.size(); i++) {
if (euclidianDistance(_f[i], _s) < (_s.size() / (double) _size))
n++;
}
return n;
}
/**
* Euclidian distance
*/
double euclidianDistance (const ObjectiveVector & _set1, const ObjectiveVector & _to, unsigned _deg = 2) {
double dist=0;
for (unsigned i=0; i<_set1.size(); i++)
dist += pow(fabs(_set1[i] - _to[i]), (int)_deg);
return pow(dist, 1.0 / _deg);
}
/**
* Removes the dominated individuals contained in _f
* @param _f a Pareto set
*/
void removeDominated(std::vector < ObjectiveVector > & _f) {
for (unsigned i=0 ; i<_f.size(); i++) {
bool dom = false;
for (unsigned j=0; j<_f.size(); j++)
if (i != j && _f[j].dominates(_f[i])) {
dom = true;
break;
}
if (dom) {
_f[i] = _f.back();
_f.pop_back();
i--;
}
}
}
/**
* Prenormalization
* @param _f a Pareto set
*/
void prenormalize (const std::vector< ObjectiveVector > & _f) {
vect_min_val.clear();
vect_max_val.clear();
for (unsigned char i=0 ; i<ObjectiveVector::nObjectives(); i++) {
float min_val = _f.front()[i], max_val = min_val;
for (unsigned j=1 ; j<_f.size(); j++) {
if (_f[j][i] < min_val)
min_val = _f[j][i];
if (_f[j][i]>max_val)
max_val = _f[j][i];
}
vect_min_val.push_back(min_val);
vect_max_val.push_back (max_val);
}
}
/**
* Normalization
* @param _f a Pareto set
*/
void normalize (std::vector< ObjectiveVector > & _f) {
for (unsigned i=0 ; i<ObjectiveVector::nObjectives(); i++)
for (unsigned j=0; j<_f.size(); j++)
_f[j][i] = (_f[j][i] - vect_min_val[i]) / (vect_max_val[i] - vect_min_val[i]);
}
/**
* Computation of the union of _f1 and _f2 in _f
* @param _f1 the first Pareto set
* @param _f2 the second Pareto set
* @param _f the final Pareto set
*/
void computeUnion(const std::vector< ObjectiveVector > & _f1, const std::vector< ObjectiveVector > & _f2, std::vector< ObjectiveVector > & _f) {
_f = _f1 ;
for (unsigned i=0; i<_f2.size(); i++) {
bool b = false;
for (unsigned j=0; j<_f1.size(); j ++)
if (_f1[j] == _f2[i]) {
b = true;
break;
}
if (! b)
_f.push_back(_f2[i]);
}
}
/**
* How many in niche
*/
unsigned howManyInNicheOf (const std::vector< ObjectiveVector > & _f, const ObjectiveVector & _s, unsigned _size) {
unsigned n=0;
for (unsigned i=0 ; i<_f.size(); i++) {
if (euclidianDistance(_f[i], _s) < (_s.size() / (double) _size))
n++;
}
return n;
}
/**
* Euclidian distance
*/
double euclidianDistance (const ObjectiveVector & _set1, const ObjectiveVector & _to, unsigned _deg = 2) {
double dist=0;
for (unsigned i=0; i<_set1.size(); i++)
dist += pow(fabs(_set1[i] - _to[i]), (int)_deg);
return pow(dist, 1.0 / _deg);
}
};

View file

@ -19,7 +19,7 @@
* Base class for performance metrics (also known as quality indicators).
*/
class moeoMetric : public eoFunctorBase
{};
{};
/**
@ -27,7 +27,7 @@ class moeoMetric : public eoFunctorBase
*/
template < class A, class R >
class moeoUnaryMetric : public eoUF < A, R >, public moeoMetric
{};
{};
/**
@ -35,7 +35,7 @@ class moeoUnaryMetric : public eoUF < A, R >, public moeoMetric
*/
template < class A1, class A2, class R >
class moeoBinaryMetric : public eoBF < A1, A2, R >, public moeoMetric
{};
{};
/**
@ -43,7 +43,7 @@ class moeoBinaryMetric : public eoBF < A1, A2, R >, public moeoMetric
*/
template < class ObjectiveVector, class R >
class moeoSolutionUnaryMetric : public moeoUnaryMetric < const ObjectiveVector &, R >
{};
{};
/**
@ -51,7 +51,7 @@ class moeoSolutionUnaryMetric : public moeoUnaryMetric < const ObjectiveVector &
*/
template < class ObjectiveVector, class R >
class moeoVectorUnaryMetric : public moeoUnaryMetric < const std::vector < ObjectiveVector > &, R >
{};
{};
/**
@ -59,7 +59,7 @@ class moeoVectorUnaryMetric : public moeoUnaryMetric < const std::vector < Objec
*/
template < class ObjectiveVector, class R >
class moeoSolutionVsSolutionBinaryMetric : public moeoBinaryMetric < const ObjectiveVector &, const ObjectiveVector &, R >
{};
{};
/**
@ -67,7 +67,7 @@ class moeoSolutionVsSolutionBinaryMetric : public moeoBinaryMetric < const Objec
*/
template < class ObjectiveVector, class R >
class moeoVectorVsVectorBinaryMetric : public moeoBinaryMetric < const std::vector < ObjectiveVector > &, const std::vector < ObjectiveVector > &, R >
{};
{};
#endif /*MOEOMETRIC_H_*/

View file

@ -26,118 +26,118 @@ template < class ObjectiveVector, class R >
class moeoNormalizedSolutionVsSolutionBinaryMetric : public moeoSolutionVsSolutionBinaryMetric < ObjectiveVector, R >
{
public:
/** very small value to avoid the extreme case where the min bound == the max bound */
const static double tiny = 1e-6;
/** very small value to avoid the extreme case where the min bound == the max bound */
const static double tiny = 1e-6;
/**
* Default ctr for any moeoNormalizedSolutionVsSolutionBinaryMetric object
*/
moeoNormalizedSolutionVsSolutionBinaryMetric()
{
bounds.resize(ObjectiveVector::Traits::nObjectives());
}
/**
* Sets the lower bound (_min) and the upper bound (_max) for the objective _obj
* _min lower bound
* _max upper bound
* _obj the objective index
*/
void setup(double _min, double _max, unsigned _obj)
{
if (_min == _max)
{
_min -= tiny;
_max += tiny;
}
bounds[_obj] = eoRealInterval(_min, _max);
}
/**
* Sets the lower bound and the upper bound for the objective _obj using a eoRealInterval object
* _realInterval the eoRealInterval object
* _obj the objective index
*/
virtual void setup(eoRealInterval _realInterval, unsigned _obj)
{
bounds[_obj] = _realInterval;
}
/**
* Default ctr for any moeoNormalizedSolutionVsSolutionBinaryMetric object
*/
moeoNormalizedSolutionVsSolutionBinaryMetric()
{
bounds.resize(ObjectiveVector::Traits::nObjectives());
}
/**
* Sets the lower bound (_min) and the upper bound (_max) for the objective _obj
* _min lower bound
* _max upper bound
* _obj the objective index
*/
void setup(double _min, double _max, unsigned _obj)
{
if (_min == _max)
{
_min -= tiny;
_max += tiny;
}
bounds[_obj] = eoRealInterval(_min, _max);
}
/**
* Sets the lower bound and the upper bound for the objective _obj using a eoRealInterval object
* _realInterval the eoRealInterval object
* _obj the objective index
*/
virtual void setup(eoRealInterval _realInterval, unsigned _obj)
{
bounds[_obj] = _realInterval;
}
protected:
/** the bounds for every objective (bounds[i] = bounds for the objective i) */
std::vector < eoRealInterval > bounds;
/** the bounds for every objective (bounds[i] = bounds for the objective i) */
std::vector < eoRealInterval > bounds;
};
/**
* Additive epsilon binary metric allowing to compare two objective vectors as proposed in
* Zitzler E., Thiele L., Laumanns M., Fonseca C. M., Grunert da Fonseca V.:
* Zitzler E., Thiele L., Laumanns M., Fonseca C. M., Grunert da Fonseca V.:
* Performance Assessment of Multiobjective Optimizers: An Analysis and Review. IEEE Transactions on Evolutionary Computation 7(2), pp.117–132 (2003).
*/
template < class ObjectiveVector >
class moeoAdditiveEpsilonBinaryMetric : public moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double >
{
public:
/**
* Returns the minimal distance by which the objective vector _o1 must be translated in all objectives
* so that it weakly dominates the objective vector _o2
* @warning don't forget to set the bounds for every objective before the call of this function
* @param _o1 the first objective vector
* @param _o2 the second objective vector
*/
double operator()(const ObjectiveVector & _o1, const ObjectiveVector & _o2)
{
// computation of the epsilon value for the first objective
double result = epsilon(_o1, _o2, 0);
// computation of the epsilon value for the other objectives
double tmp;
for (unsigned i=1; i<ObjectiveVector::Traits::nObjectives(); i++)
{
tmp = epsilon(_o1, _o2, i);
result = std::max(result, tmp);
}
// returns the maximum epsilon value
return result;
}
/**
* Returns the minimal distance by which the objective vector _o1 must be translated in all objectives
* so that it weakly dominates the objective vector _o2
* @warning don't forget to set the bounds for every objective before the call of this function
* @param _o1 the first objective vector
* @param _o2 the second objective vector
*/
double operator()(const ObjectiveVector & _o1, const ObjectiveVector & _o2)
{
// computation of the epsilon value for the first objective
double result = epsilon(_o1, _o2, 0);
// computation of the epsilon value for the other objectives
double tmp;
for (unsigned i=1; i<ObjectiveVector::Traits::nObjectives(); i++)
{
tmp = epsilon(_o1, _o2, i);
result = std::max(result, tmp);
}
// returns the maximum epsilon value
return result;
}
private:
/** the bounds for every objective */
using moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > :: bounds;
/**
* Returns the epsilon value by which the objective vector _o1 must be translated in the objective _obj
* so that it dominates the objective vector _o2
* @param _o1 the first objective vector
* @param _o2 the second objective vector
* @param _obj the index of the objective
*/
double epsilon(const ObjectiveVector & _o1, const ObjectiveVector & _o2, const unsigned _obj)
{
double result;
// if the objective _obj have to be minimized
if (ObjectiveVector::Traits::minimizing(_obj))
{
// _o1[_obj] - _o2[_obj]
result = ( (_o1[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ) - ( (_o2[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() );
}
// if the objective _obj have to be maximized
else
{
// _o2[_obj] - _o1[_obj]
result = ( (_o2[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ) - ( (_o1[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() );
}
return result;
}
/** the bounds for every objective */
using moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > :: bounds;
/**
* Returns the epsilon value by which the objective vector _o1 must be translated in the objective _obj
* so that it dominates the objective vector _o2
* @param _o1 the first objective vector
* @param _o2 the second objective vector
* @param _obj the index of the objective
*/
double epsilon(const ObjectiveVector & _o1, const ObjectiveVector & _o2, const unsigned _obj)
{
double result;
// if the objective _obj have to be minimized
if (ObjectiveVector::Traits::minimizing(_obj))
{
// _o1[_obj] - _o2[_obj]
result = ( (_o1[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ) - ( (_o2[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() );
}
// if the objective _obj have to be maximized
else
{
// _o2[_obj] - _o1[_obj]
result = ( (_o2[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() ) - ( (_o1[_obj] - bounds[_obj].minimum()) / bounds[_obj].range() );
}
return result;
}
};
@ -146,7 +146,7 @@ private:
* Hypervolume binary metric allowing to compare two objective vectors as proposed in
* Zitzler E., Künzli S.: Indicator-Based Selection in Multiobjective Search. In Parallel Problem Solving from Nature (PPSN VIII).
* Lecture Notes in Computer Science 3242, Springer, Birmingham, UK pp.832–842 (2004).
* This indicator is based on the hypervolume concept introduced in
* This indicator is based on the hypervolume concept introduced in
* Zitzler, E., Thiele, L.: Multiobjective Optimization Using Evolutionary Algorithms - A Comparative Case Study.
* Parallel Problem Solving from Nature (PPSN-V), pp.292-301 (1998).
*/
@ -155,111 +155,111 @@ class moeoHypervolumeBinaryMetric : public moeoNormalizedSolutionVsSolutionBinar
{
public:
/**
* Ctor
* @param _rho value used to compute the reference point from the worst values for each objective (default : 1.1)
*/
moeoHypervolumeBinaryMetric(double _rho = 1.1) : rho(_rho)
{
// not-a-maximization problem check
for (unsigned i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
{
if (ObjectiveVector::Traits::maximizing(i))
{
throw std::runtime_error("Hypervolume binary metric not yet implemented for a maximization problem in moeoHypervolumeBinaryMetric");
}
}
// consistency check
if (rho < 1)
{
cout << "Warning, value used to compute the reference point rho for the hypervolume calculation must not be smaller than 1" << endl;
cout << "Adjusted to 1" << endl;
rho = 1;
}
}
/**
* Returns the volume of the space that is dominated by _o2 but not by _o1 with respect to a reference point computed using rho.
* @warning don't forget to set the bounds for every objective before the call of this function
* @param _o1 the first objective vector
* @param _o2 the second objective vector
*/
double operator()(const ObjectiveVector & _o1, const ObjectiveVector & _o2)
{
double result;
// if _o1 dominates _o2
if ( paretoComparator(_o1,_o2) )
{
result = - hypervolume(_o1, _o2, ObjectiveVector::Traits::nObjectives()-1);
}
else
{
result = hypervolume(_o2, _o1, ObjectiveVector::Traits::nObjectives()-1);
}
return result;
}
/**
* Ctor
* @param _rho value used to compute the reference point from the worst values for each objective (default : 1.1)
*/
moeoHypervolumeBinaryMetric(double _rho = 1.1) : rho(_rho)
{
// not-a-maximization problem check
for (unsigned i=0; i<ObjectiveVector::Traits::nObjectives(); i++)
{
if (ObjectiveVector::Traits::maximizing(i))
{
throw std::runtime_error("Hypervolume binary metric not yet implemented for a maximization problem in moeoHypervolumeBinaryMetric");
}
}
// consistency check
if (rho < 1)
{
cout << "Warning, value used to compute the reference point rho for the hypervolume calculation must not be smaller than 1" << endl;
cout << "Adjusted to 1" << endl;
rho = 1;
}
}
/**
* Returns the volume of the space that is dominated by _o2 but not by _o1 with respect to a reference point computed using rho.
* @warning don't forget to set the bounds for every objective before the call of this function
* @param _o1 the first objective vector
* @param _o2 the second objective vector
*/
double operator()(const ObjectiveVector & _o1, const ObjectiveVector & _o2)
{
double result;
// if _o1 dominates _o2
if ( paretoComparator(_o1,_o2) )
{
result = - hypervolume(_o1, _o2, ObjectiveVector::Traits::nObjectives()-1);
}
else
{
result = hypervolume(_o2, _o1, ObjectiveVector::Traits::nObjectives()-1);
}
return result;
}
private:
/** value used to compute the reference point from the worst values for each objective */
double rho;
/** the bounds for every objective */
using moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > :: bounds;
/** Functor to compare two objective vectors according to Pareto dominance relation */
moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
/**
* Returns the volume of the space that is dominated by _o2 but not by _o1 with respect to a reference point computed using rho for the objective _obj.
* @param _o1 the first objective vector
* @param _o2 the second objective vector
* @param _obj the objective index
* @param _flag used for iteration, if _flag=true _o2 is not talen into account (default : false)
*/
double hypervolume(const ObjectiveVector & _o1, const ObjectiveVector & _o2, const unsigned _obj, const bool _flag = false)
{
double result;
double range = rho * bounds[_obj].range();
double max = bounds[_obj].minimum() + range;
// value of _1 for the objective _obj
double v1 = _o1[_obj];
// value of _2 for the objective _obj (if _flag=true, v2=max)
double v2;
if (_flag)
{
v2 = max;
}
else
{
v2 = _o2[_obj];
}
// computation of the volume
if (_obj == 0)
{
if (v1 < v2)
{
result = (v2 - v1) / range;
}
else
{
result = 0;
}
}
else
{
if (v1 < v2)
{
result = ( hypervolume(_o1, _o2, _obj-1, true) * (v2 - v1) / range ) + ( hypervolume(_o1, _o2, _obj-1) * (max - v2) / range );
}
else
{
result = hypervolume(_o1, _o2, _obj-1) * (max - v2) / range;
}
}
return result;
}
/** value used to compute the reference point from the worst values for each objective */
double rho;
/** the bounds for every objective */
using moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > :: bounds;
/** Functor to compare two objective vectors according to Pareto dominance relation */
moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
/**
* Returns the volume of the space that is dominated by _o2 but not by _o1 with respect to a reference point computed using rho for the objective _obj.
* @param _o1 the first objective vector
* @param _o2 the second objective vector
* @param _obj the objective index
* @param _flag used for iteration, if _flag=true _o2 is not talen into account (default : false)
*/
double hypervolume(const ObjectiveVector & _o1, const ObjectiveVector & _o2, const unsigned _obj, const bool _flag = false)
{
double result;
double range = rho * bounds[_obj].range();
double max = bounds[_obj].minimum() + range;
// value of _1 for the objective _obj
double v1 = _o1[_obj];
// value of _2 for the objective _obj (if _flag=true, v2=max)
double v2;
if (_flag)
{
v2 = max;
}
else
{
v2 = _o2[_obj];
}
// computation of the volume
if (_obj == 0)
{
if (v1 < v2)
{
result = (v2 - v1) / range;
}
else
{
result = 0;
}
}
else
{
if (v1 < v2)
{
result = ( hypervolume(_o1, _o2, _obj-1, true) * (v2 - v1) / range ) + ( hypervolume(_o1, _o2, _obj-1) * (max - v2) / range );
}
else
{
result = hypervolume(_o1, _o2, _obj-1) * (max - v2) / range;
}
}
return result;
}
};

View file

@ -24,155 +24,155 @@ class moeoArchive : public eoPop < MOEOT >
{
public:
using std::vector < MOEOT > :: size;
using std::vector < MOEOT > :: operator[];
using std::vector < MOEOT > :: back;
using std::vector < MOEOT > :: pop_back;
/**
* The type of an objective vector for a solution
*/
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Default ctor.
* The moeoObjectiveVectorComparator used to compare solutions is based on Pareto dominance
*/
moeoArchive() : eoPop < MOEOT >(), comparator(paretoComparator)
{}
/**
* Ctor
* @param _comparator the moeoObjectiveVectorComparator used to compare solutions
*/
moeoArchive(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator) : eoPop < MOEOT >(), comparator(_comparator)
{}
/**
* Returns true if the current archive dominates _objectiveVector according to the moeoObjectiveVectorComparator given in the constructor
* @param _objectiveVector the objective vector to compare with the current archive
*/
bool dominates (const ObjectiveVector & _objectiveVector) const
{
for (unsigned i = 0; i<size(); i++)
{
if ( comparator(operator[](i).fitness(), _objectiveVector) )
{
return true;
}
}
return false;
}
/**
* Returns true if the current archive already contains a solution with the same objective values than _objectiveVector
* @param _objectiveVector the objective vector to compare with the current archive
*/
bool contains (const ObjectiveVector & _objectiveVector) const
{
for (unsigned i = 0; i<size(); i++)
{
if (operator[](i).objectiveVector() == _objectiveVector)
{
return true;
}
}
return false;
}
/**
* Updates the archive with a given individual _moeo
* @param _moeo the given individual
*/
void update (const MOEOT & _moeo)
{
// first step: removing the dominated solutions from the archive
for (unsigned j=0; j<size();)
{
// if _moeo dominates the jth solution contained in the archive
if ( comparator(_moeo.objectiveVector(), operator[](j).objectiveVector()) )
{
operator[](j) = back();
pop_back();
}
else if (_moeo.objectiveVector() == operator[](j).objectiveVector())
{
operator[](j) = back();
pop_back();
}
else
{
j++;
}
}
// second step: is _moeo dominated?
bool dom = false;
for (unsigned j=0; j<size(); j++)
{
// if the jth solution contained in the archive dominates _moeo
if ( comparator(operator[](j).objectiveVector(), _moeo.objectiveVector()) )
{
dom = true;
break;
}
}
if (!dom)
{
push_back(_moeo);
}
}
/**
* Updates the archive with a given population _pop
* @param _pop the given population
*/
void update (const eoPop < MOEOT > & _pop)
{
for (unsigned i=0; i<_pop.size(); i++)
{
update(_pop[i]);
}
}
using std::vector < MOEOT > :: size;
using std::vector < MOEOT > :: operator[];
using std::vector < MOEOT > :: back;
using std::vector < MOEOT > :: pop_back;
/**
* Returns true if the current archive contains the same objective vectors
* than the given archive _arch
* @param _arch the given archive
*/
bool equals (const moeoArchive < MOEOT > & _arch)
{
for (unsigned i=0; i<size(); i++)
{
if (! _arch.contains(operator[](i).objectiveVector()))
{
return false;
}
}
for (unsigned i=0; i<_arch.size() ; i++)
{
if (! contains(_arch[i].objectiveVector()))
{
return false;
}
}
return true;
}
/**
* The type of an objective vector for a solution
*/
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Default ctor.
* The moeoObjectiveVectorComparator used to compare solutions is based on Pareto dominance
*/
moeoArchive() : eoPop < MOEOT >(), comparator(paretoComparator)
{}
/**
* Ctor
* @param _comparator the moeoObjectiveVectorComparator used to compare solutions
*/
moeoArchive(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator) : eoPop < MOEOT >(), comparator(_comparator)
{}
/**
* Returns true if the current archive dominates _objectiveVector according to the moeoObjectiveVectorComparator given in the constructor
* @param _objectiveVector the objective vector to compare with the current archive
*/
bool dominates (const ObjectiveVector & _objectiveVector) const
{
for (unsigned i = 0; i<size(); i++)
{
if ( comparator(operator[](i).fitness(), _objectiveVector) )
{
return true;
}
}
return false;
}
/**
* Returns true if the current archive already contains a solution with the same objective values than _objectiveVector
* @param _objectiveVector the objective vector to compare with the current archive
*/
bool contains (const ObjectiveVector & _objectiveVector) const
{
for (unsigned i = 0; i<size(); i++)
{
if (operator[](i).objectiveVector() == _objectiveVector)
{
return true;
}
}
return false;
}
/**
* Updates the archive with a given individual _moeo
* @param _moeo the given individual
*/
void update (const MOEOT & _moeo)
{
// first step: removing the dominated solutions from the archive
for (unsigned j=0; j<size();)
{
// if _moeo dominates the jth solution contained in the archive
if ( comparator(_moeo.objectiveVector(), operator[](j).objectiveVector()) )
{
operator[](j) = back();
pop_back();
}
else if (_moeo.objectiveVector() == operator[](j).objectiveVector())
{
operator[](j) = back();
pop_back();
}
else
{
j++;
}
}
// second step: is _moeo dominated?
bool dom = false;
for (unsigned j=0; j<size(); j++)
{
// if the jth solution contained in the archive dominates _moeo
if ( comparator(operator[](j).objectiveVector(), _moeo.objectiveVector()) )
{
dom = true;
break;
}
}
if (!dom)
{
push_back(_moeo);
}
}
/**
* Updates the archive with a given population _pop
* @param _pop the given population
*/
void update (const eoPop < MOEOT > & _pop)
{
for (unsigned i=0; i<_pop.size(); i++)
{
update(_pop[i]);
}
}
/**
* Returns true if the current archive contains the same objective vectors
* than the given archive _arch
* @param _arch the given archive
*/
bool equals (const moeoArchive < MOEOT > & _arch)
{
for (unsigned i=0; i<size(); i++)
{
if (! _arch.contains(operator[](i).objectiveVector()))
{
return false;
}
}
for (unsigned i=0; i<_arch.size() ; i++)
{
if (! contains(_arch[i].objectiveVector()))
{
return false;
}
}
return true;
}
private:
/** The moeoObjectiveVectorComparator used to compare solutions */
moeoObjectiveVectorComparator < ObjectiveVector > & comparator;
/** A moeoObjectiveVectorComparator based on Pareto dominance (used as default) */
moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
/** The moeoObjectiveVectorComparator used to compare solutions */
moeoObjectiveVectorComparator < ObjectiveVector > & comparator;
/** A moeoObjectiveVectorComparator based on Pareto dominance (used as default) */
moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator;
};

View file

@ -29,41 +29,41 @@ class moeoArchiveFitnessSavingUpdater : public eoUpdater
{
public:
/**
* Ctor
* @param _arch local archive
* @param _filename target filename
* @param _id own ID
*/
moeoArchiveFitnessSavingUpdater (moeoArchive<EOT> & _arch, const std::string & _filename = "Res/Arch", int _id = -1) : arch(_arch), filename(_filename), id(_id), counter(0)
{}
/**
* Ctor
* @param _arch local archive
* @param _filename target filename
* @param _id own ID
*/
moeoArchiveFitnessSavingUpdater (moeoArchive<EOT> & _arch, const std::string & _filename = "Res/Arch", int _id = -1) : arch(_arch), filename(_filename), id(_id), counter(0)
{}
/**
* Saves the fitness of the archive's members into the file
*/
void operator()() {
char buff[MAX_BUFFER_SIZE];
if (id == -1)
sprintf (buff, "%s.%u", filename.c_str(), counter ++);
else
sprintf (buff, "%s.%u.%u", filename.c_str(), id, counter ++);
std::ofstream f(buff);
for (unsigned i = 0; i < arch.size (); i++)
f << arch[i].objectiveVector() << std::endl;
f.close ();
}
/**
* Saves the fitness of the archive's members into the file
*/
void operator()() {
char buff[MAX_BUFFER_SIZE];
if (id == -1)
sprintf (buff, "%s.%u", filename.c_str(), counter ++);
else
sprintf (buff, "%s.%u.%u", filename.c_str(), id, counter ++);
std::ofstream f(buff);
for (unsigned i = 0; i < arch.size (); i++)
f << arch[i].objectiveVector() << std::endl;
f.close ();
}
private:
/** local archive */
moeoArchive<EOT> & arch;
/** target filename */
std::string filename;
/** own ID */
int id;
/** counter */
unsigned counter;
/** local archive */
moeoArchive<EOT> & arch;
/** target filename */
std::string filename;
/** own ID */
int id;
/** counter */
unsigned counter;
};

View file

@ -24,30 +24,30 @@ template < class EOT >
class moeoArchiveUpdater : public eoUpdater
{
public:
/**
* Ctor
* @param _arch an archive of non-dominated solutions
* @param _pop the main population
*/
moeoArchiveUpdater(moeoArchive <EOT> & _arch, const eoPop<EOT> & _pop) : arch(_arch), pop(_pop)
{}
/**
* Updates the archive with newly found non-dominated solutions contained in the main population
*/
void operator()() {
arch.update(pop);
}
/**
* Ctor
* @param _arch an archive of non-dominated solutions
* @param _pop the main population
*/
moeoArchiveUpdater(moeoArchive <EOT> & _arch, const eoPop<EOT> & _pop) : arch(_arch), pop(_pop)
{}
/**
* Updates the archive with newly found non-dominated solutions contained in the main population
*/
void operator()() {
arch.update(pop);
}
private:
/** the archive of non-dominated solutions */
moeoArchive<EOT> & arch;
/** the main population */
const eoPop<EOT> & pop;
/** the archive of non-dominated solutions */
moeoArchive<EOT> & arch;
/** the main population */
const eoPop<EOT> & pop;
};

View file

@ -17,50 +17,50 @@
#include <moeoLS.h>
/**
* This class allows to embed a set of local searches that are sequentially applied,
* This class allows to embed a set of local searches that are sequentially applied,
* and so working and updating the same archive of non-dominated solutions.
*/
template < class MOEOT, class Type >
class moeoCombinedLS : public moeoLS < MOEOT, Type >
{
public:
/**
* Ctor
* @param _eval the full evaluator of a solution
* @param _first_mols the first multi-objective local search to add
*/
moeoCombinedLS(moeoLS < MOEOT, Type > & _first_mols)
{
combinedLS.push_back (& _first_mols);
}
/**
* Adds a new local search to combine
* @param _mols the multi-objective local search to add
*/
void add(moeoLS < MOEOT, Type > & _mols)
{
combinedLS.push_back(& _mols);
}
/**
* Gives a new solution in order to explore the neigborhood.
* The new non-dominated solutions are added to the archive
* @param _moeo the solution
* @param _arch the archive of non-dominated solutions
*/
void operator () (Type _type, moeoArchive < MOEOT > & _arch)
{
for (unsigned i=0; i<combinedLS.size(); i++)
combinedLS[i] -> operator()(_type, _arch);
}
/**
* Ctor
* @param _eval the full evaluator of a solution
* @param _first_mols the first multi-objective local search to add
*/
moeoCombinedLS(moeoLS < MOEOT, Type > & _first_mols)
{
combinedLS.push_back (& _first_mols);
}
/**
* Adds a new local search to combine
* @param _mols the multi-objective local search to add
*/
void add(moeoLS < MOEOT, Type > & _mols)
{
combinedLS.push_back(& _mols);
}
/**
* Gives a new solution in order to explore the neigborhood.
* The new non-dominated solutions are added to the archive
* @param _moeo the solution
* @param _arch the archive of non-dominated solutions
*/
void operator () (Type _type, moeoArchive < MOEOT > & _arch)
{
for (unsigned i=0; i<combinedLS.size(); i++)
combinedLS[i] -> operator()(_type, _arch);
}
private:
/** the vector that contains the combined LS */
std::vector< moeoLS < MOEOT, Type > * > combinedLS;
/** the vector that contains the combined LS */
std::vector< moeoLS < MOEOT, Type > * > combinedLS;
};

View file

@ -20,7 +20,7 @@
*/
template < class MOEOT >
class moeoComparator : public eoBF < const MOEOT &, const MOEOT &, const bool >
{};
{};
/**
@ -30,15 +30,15 @@ template < class MOEOT >
class moeoObjectiveComparator : public moeoComparator < MOEOT >
{
public:
/**
* Returns true if _moeo1 is greater than _moeo2 on the first objective, then on the second, and so on
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
return _moeo1.objectiveVector() > _moeo2.objectiveVector();
}
/**
* Returns true if _moeo1 is greater than _moeo2 on the first objective, then on the second, and so on
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
return _moeo1.objectiveVector() > _moeo2.objectiveVector();
}
};
/**
@ -48,31 +48,31 @@ template < class MOEOT >
class moeoOneObjectiveComparator : public moeoComparator < MOEOT >
{
public:
/**
* Ctor.
* @param _obj the index of objective
*/
moeoOneObjectiveComparator(unsigned _obj) : obj(_obj)
{
if (obj > MOEOT::ObjectiveVector::nObjectives())
{
throw std::runtime_error("Problem with the index of objective in moeoOneObjectiveComparator");
}
}
/**
* Returns true if _moeo1 is greater than _moeo2 on the obj objective
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
return _moeo1.objectiveVector()[obj] > _moeo2.objectiveVector()[obj];
}
/**
* Ctor.
* @param _obj the index of objective
*/
moeoOneObjectiveComparator(unsigned _obj) : obj(_obj)
{
if (obj > MOEOT::ObjectiveVector::nObjectives())
{
throw std::runtime_error("Problem with the index of objective in moeoOneObjectiveComparator");
}
}
/**
* Returns true if _moeo1 is greater than _moeo2 on the obj objective
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
return _moeo1.objectiveVector()[obj] > _moeo2.objectiveVector()[obj];
}
private:
unsigned obj;
unsigned obj;
};
@ -84,22 +84,22 @@ template < class MOEOT >
class moeoFitnessThenDiversityComparator : public moeoComparator < MOEOT >
{
public:
/**
* Returns true if _moeo1 is greater than _moeo2 according to their fitness values, then according to their diversity values
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
if (_moeo1.fitness() == _moeo2.fitness())
{
return _moeo1.diversity() > _moeo2.diversity();
}
else
{
return _moeo1.fitness() > _moeo2.fitness();
}
}
/**
* Returns true if _moeo1 is greater than _moeo2 according to their fitness values, then according to their diversity values
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
if (_moeo1.fitness() == _moeo2.fitness())
{
return _moeo1.diversity() > _moeo2.diversity();
}
else
{
return _moeo1.fitness() > _moeo2.fitness();
}
}
};
@ -110,22 +110,22 @@ template < class MOEOT >
class moeoDiversityThenFitnessComparator : public moeoComparator < MOEOT >
{
public:
/**
* Returns true if _moeo1 is greater than _moeo2 according to their diversity values, then according to their fitness values
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
if (_moeo1.diversity() == _moeo2.diversity())
{
return _moeo1.fitness() > _moeo2.fitness();
}
else
{
return _moeo1.diversity() > _moeo2.diversity();
}
}
/**
* Returns true if _moeo1 is greater than _moeo2 according to their diversity values, then according to their fitness values
* @param _moeo1 the first solution
* @param _moeo2 the second solution
*/
const bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
if (_moeo1.diversity() == _moeo2.diversity())
{
return _moeo1.fitness() > _moeo2.fitness();
}
else
{
return _moeo1.diversity() > _moeo2.diversity();
}
}
};

View file

@ -23,20 +23,20 @@ class moeoConvertPopToObjectiveVectors : public eoUF < const eoPop < MOEOT >, co
{
public:
/**
* Returns a vector of the objective vectors from the population _pop
* @param _pop the population
*/
const std::vector < ObjectiveVector > operator()(const eoPop < MOEOT > _pop)
{
std::vector < ObjectiveVector > result;
result.resize(_pop.size());
for (unsigned i=0; i<_pop.size(); i++)
{
result.push_back(_pop[i].objectiveVector());
}
return result;
}
/**
* Returns a vector of the objective vectors from the population _pop
* @param _pop the population
*/
const std::vector < ObjectiveVector > operator()(const eoPop < MOEOT > _pop)
{
std::vector < ObjectiveVector > result;
result.resize(_pop.size());
for (unsigned i=0; i<_pop.size(); i++)
{
result.push_back(_pop[i].objectiveVector());
}
return result;
}
};
#endif /*MOEOPOPTOOBJECTIVEVECTORS_H_*/

View file

@ -18,7 +18,7 @@
#include <moeoDiversityAssignment.h>
/**
* Diversity assignment sheme based on crowding distance proposed in:
* Diversity assignment sheme based on crowding distance proposed in:
* K. Deb, A. Pratap, S. Agarwal, T. Meyarivan, "A Fast and Elitist Multi-Objective Genetic Algorithm: NSGA-II", IEEE Transactions on Evolutionary Computation, vol. 6, no. 2 (2002).
* This strategy is, for instance, used in NSGA-II.
*/
@ -27,89 +27,89 @@ class moeoCrowdingDistanceDiversityAssignment : public moeoDiversityAssignment <
{
public:
/** the objective vector type of the solutions */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Returns a big value (regarded as infinite)
*/
double inf() const
{
return std::numeric_limits<double>::max();
}
/**
* Computes diversity values for every solution contained in the population _pop
* @param _pop the population
*/
void operator()(eoPop < MOEOT > & _pop)
{
// number of objectives for the problem under consideration
unsigned nObjectives = MOEOT::ObjectiveVector::nObjectives();
if (_pop.size() <= 2)
{
for (unsigned i=0; i<_pop.size(); i++)
{
_pop[i].diversity(inf());
}
}
else
{
setDistances(_pop);
}
}
/** the objective vector type of the solutions */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Returns a big value (regarded as infinite)
*/
double inf() const
{
return std::numeric_limits<double>::max();
}
/**
* Computes diversity values for every solution contained in the population _pop
* @param _pop the population
*/
void operator()(eoPop < MOEOT > & _pop)
{
// number of objectives for the problem under consideration
unsigned nObjectives = MOEOT::ObjectiveVector::nObjectives();
if (_pop.size() <= 2)
{
for (unsigned i=0; i<_pop.size(); i++)
{
_pop[i].diversity(inf());
}
}
else
{
setDistances(_pop);
}
}
/**
* @warning NOT IMPLEMENTED, DO NOTHING !
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objVec the objective vector
* @warning NOT IMPLEMENTED, DO NOTHING !
*/
void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
{
cout << "WARNING : updateByDeleting not implemented in moeoCrowdingDiversityAssignment" << endl;
}
/**
* @warning NOT IMPLEMENTED, DO NOTHING !
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objVec the objective vector
* @warning NOT IMPLEMENTED, DO NOTHING !
*/
void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
{
cout << "WARNING : updateByDeleting not implemented in moeoCrowdingDiversityAssignment" << endl;
}
private:
/**
* Sets the distance values
* @param _pop the population
*/
void setDistances (eoPop < MOEOT > & _pop)
{
double min, max, distance;
unsigned nObjectives = MOEOT::ObjectiveVector::nObjectives();
// set diversity to 0
for (unsigned i=0; i<_pop.size(); i++)
{
_pop[i].diversity(0);
}
// for each objective
for (unsigned obj=0; obj<nObjectives; obj++)
{
// comparator
moeoOneObjectiveComparator < MOEOT > comp(obj);
// sort
std::sort(_pop.begin(), _pop.end(), comp);
// min & max
min = _pop[0].objectiveVector()[obj];
max = _pop[_pop.size()-1].objectiveVector()[obj];
// set the diversity value to infiny for min and max
_pop[0].diversity(inf());
_pop[_pop.size()-1].diversity(inf());
for (unsigned i=1; i<_pop.size()-1; i++)
{
distance = (_pop[i+1].objectiveVector()[obj] - _pop[i-1].objectiveVector()[obj]) / (max-min);
_pop[i].diversity(_pop[i].diversity() + distance);
}
}
}
/**
* Sets the distance values
* @param _pop the population
*/
void setDistances (eoPop < MOEOT > & _pop)
{
double min, max, distance;
unsigned nObjectives = MOEOT::ObjectiveVector::nObjectives();
// set diversity to 0
for (unsigned i=0; i<_pop.size(); i++)
{
_pop[i].diversity(0);
}
// for each objective
for (unsigned obj=0; obj<nObjectives; obj++)
{
// comparator
moeoOneObjectiveComparator < MOEOT > comp(obj);
// sort
std::sort(_pop.begin(), _pop.end(), comp);
// min & max
min = _pop[0].objectiveVector()[obj];
max = _pop[_pop.size()-1].objectiveVector()[obj];
// set the diversity value to infiny for min and max
_pop[0].diversity(inf());
_pop[_pop.size()-1].diversity(inf());
for (unsigned i=1; i<_pop.size()-1; i++)
{
distance = (_pop[i+1].objectiveVector()[obj] - _pop[i-1].objectiveVector()[obj]) / (max-min);
_pop[i].diversity(_pop[i].diversity() + distance);
}
}
}
};

View file

@ -22,30 +22,30 @@
template < class MOEOT >
class moeoDiversityAssignment : public eoUF < eoPop < MOEOT > &, void >
{
public:
public:
/** The type for objective vector */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objecVec the objective vector
*/
virtual void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec) = 0;
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the individual _moeo into account.
* @param _pop the population
* @param _moeo the individual
*/
void updateByDeleting(eoPop < MOEOT > & _pop, MOEOT & _moeo)
{
updateByDeleting(_pop, _moeo.objectiveVector());
}
/** The type for objective vector */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objecVec the objective vector
*/
virtual void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec) = 0;
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the individual _moeo into account.
* @param _pop the population
* @param _moeo the individual
*/
void updateByDeleting(eoPop < MOEOT > & _pop, MOEOT & _moeo)
{
updateByDeleting(_pop, _moeo.objectiveVector());
}
};
@ -57,37 +57,37 @@ class moeoDummyDiversityAssignment : public moeoDiversityAssignment < MOEOT >
{
public:
/** The type for objective vector */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Sets the diversity to '0' for every individuals of the population _pop if it is invalid
* @param _pop the population
*/
void operator () (eoPop < MOEOT > & _pop)
{
for (unsigned idx = 0; idx<_pop.size (); idx++)
{
if (_pop[idx].invalidDiversity())
{
// set the diversity to 0
_pop[idx].diversity(0.0);
}
}
}
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objecVec the objective vector
*/
void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
{
// nothing to do... ;-)
}
/** The type for objective vector */
typedef typename MOEOT::ObjectiveVector ObjectiveVector;
/**
* Sets the diversity to '0' for every individuals of the population _pop if it is invalid
* @param _pop the population
*/
void operator () (eoPop < MOEOT > & _pop)
{
for (unsigned idx = 0; idx<_pop.size (); idx++)
{
if (_pop[idx].invalidDiversity())
{
// set the diversity to 0
_pop[idx].diversity(0.0);
}
}
}
/**
* Updates the diversity values of the whole population _pop by taking the deletion of the objective vector _objVec into account.
* @param _pop the population
* @param _objecVec the objective vector
*/
void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec)
{
// nothing to do... ;-)
}
};
#endif /*MOEODIVERSITYASSIGNMENT_H_*/

View file

@ -27,93 +27,93 @@
/**
* An easy class to design multi-objective evolutionary algorithms.
*/
template < class MOEOT >
template < class MOEOT >
class moeoEasyEA: public moeoEA < MOEOT >
{
public:
/**
* Ctor.
* @param _continuator the stopping criteria
* @param _eval the evaluation functions
* @param _breed the breeder
* @param _replace the replacment strategy
* @param _fitnessEval the fitness evaluation scheme
* @param _diversityEval the diversity evaluation scheme
* @param _evalFitAndDivBeforeSelection put this parameter to 'true' if you want to re-evalue the fitness and the diversity of the population before the selection process
*/
moeoEasyEA(eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoBreed < MOEOT > & _breed, eoReplacement < MOEOT > & _replace,
moeoFitnessAssignment < MOEOT > & _fitnessEval, moeoDiversityAssignment < MOEOT > & _diversityEval, bool _evalFitAndDivBeforeSelection = false)
:
continuator(_continuator), eval (_eval), loopEval(_eval), popEval(loopEval), breed(_breed), replace(_replace), fitnessEval(_fitnessEval),
diversityEval(_diversityEval), evalFitAndDivBeforeSelection(_evalFitAndDivBeforeSelection)
{}
/**
* Ctor.
* @param _continuator the stopping criteria
* @param _eval the evaluation functions
* @param _breed the breeder
* @param _replace the replacment strategy
* @param _fitnessEval the fitness evaluation scheme
* @param _diversityEval the diversity evaluation scheme
* @param _evalFitAndDivBeforeSelection put this parameter to 'true' if you want to re-evalue the fitness and the diversity of the population before the selection process
*/
moeoEasyEA(eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoBreed < MOEOT > & _breed, eoReplacement < MOEOT > & _replace,
moeoFitnessAssignment < MOEOT > & _fitnessEval, moeoDiversityAssignment < MOEOT > & _diversityEval, bool _evalFitAndDivBeforeSelection = false)
:
continuator(_continuator), eval (_eval), loopEval(_eval), popEval(loopEval), breed(_breed), replace(_replace), fitnessEval(_fitnessEval),
diversityEval(_diversityEval), evalFitAndDivBeforeSelection(_evalFitAndDivBeforeSelection)
{}
/**
* Applies a few generation of evolution to the population _pop.
* @param _pop the population
*/
virtual void operator()(eoPop < MOEOT > & _pop)
{
eoPop < MOEOT > offspring, empty_pop;
popEval(empty_pop, _pop); // A first eval of pop.
bool firstTime = true;
do
{
try
{
unsigned pSize = _pop.size();
offspring.clear(); // new offspring
// fitness and diversity assignment (if you want to or if it is the first generation)
if (evalFitAndDivBeforeSelection || firstTime)
{
firstTime = false;
fitnessEval(_pop);
diversityEval(_pop);
}
breed(_pop, offspring);
popEval(_pop, offspring); // eval of parents + offspring if necessary
replace(_pop, offspring); // after replace, the new pop. is in _pop
if (pSize > _pop.size())
{
throw std::runtime_error("Population shrinking!");
}
else if (pSize < _pop.size())
{
throw std::runtime_error("Population growing!");
}
}
catch (std::exception& e)
{
std::string s = e.what();
s.append( " in moeoEasyEA");
throw std::runtime_error( s );
}
} while (continuator(_pop));
}
/**
* Applies a few generation of evolution to the population _pop.
* @param _pop the population
*/
virtual void operator()(eoPop < MOEOT > & _pop)
{
eoPop < MOEOT > offspring, empty_pop;
popEval(empty_pop, _pop); // A first eval of pop.
bool firstTime = true;
do
{
try
{
unsigned pSize = _pop.size();
offspring.clear(); // new offspring
// fitness and diversity assignment (if you want to or if it is the first generation)
if (evalFitAndDivBeforeSelection || firstTime)
{
firstTime = false;
fitnessEval(_pop);
diversityEval(_pop);
}
breed(_pop, offspring);
popEval(_pop, offspring); // eval of parents + offspring if necessary
replace(_pop, offspring); // after replace, the new pop. is in _pop
if (pSize > _pop.size())
{
throw std::runtime_error("Population shrinking!");
}
else if (pSize < _pop.size())
{
throw std::runtime_error("Population growing!");
}
}
catch (std::exception& e)
{
std::string s = e.what();
s.append( " in moeoEasyEA");
throw std::runtime_error( s );
}
} while (continuator(_pop));
}
protected:
/** the stopping criteria */
eoContinue < MOEOT > & continuator;
/** the evaluation functions */
eoEvalFunc < MOEOT > & eval;
/** to evaluate the whole population */
eoPopLoopEval < MOEOT > loopEval;
/** to evaluate the whole population */
eoPopEvalFunc < MOEOT > & popEval;
/** the breeder */
eoBreed < MOEOT > & breed;
/** the replacment strategy */
eoReplacement < MOEOT > & replace;
/** the fitness assignment strategy */
moeoFitnessAssignment < MOEOT > & fitnessEval;
/** the diversity assignment strategy */
moeoDiversityAssignment < MOEOT > & diversityEval;
/** if this parameter is set to 'true', the fitness and the diversity of the whole population will be re-evaluated before the selection process */
bool evalFitAndDivBeforeSelection;
/** the stopping criteria */
eoContinue < MOEOT > & continuator;
/** the evaluation functions */
eoEvalFunc < MOEOT > & eval;
/** to evaluate the whole population */
eoPopLoopEval < MOEOT > loopEval;
/** to evaluate the whole population */
eoPopEvalFunc < MOEOT > & popEval;
/** the breeder */
eoBreed < MOEOT > & breed;
/** the replacment strategy */
eoReplacement < MOEOT > & replace;
/** the fitness assignment strategy */
moeoFitnessAssignment < MOEOT > & fitnessEval;
/** the diversity assignment strategy */
moeoDiversityAssignment < MOEOT > & diversityEval;
/** if this parameter is set to 'true', the fitness and the diversity of the whole population will be re-evaluated before the selection process */
bool evalFitAndDivBeforeSelection;
};

View file

@ -28,117 +28,117 @@ template < class MOEOT > class moeoElitistReplacement:public moeoReplacement < M
{
public:
/**
* Full constructor.
* @param _evalFitness the fitness assignment strategy
* @param _evalDiversity the diversity assignment strategy
* @param _comparator the comparator (used to compare 2 individuals)
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoDiversityAssignment < MOEOT > & _evalDiversity, moeoComparator < MOEOT > & _comparator) :
evalFitness (_evalFitness), evalDiversity (_evalDiversity), comparator (_comparator)
{}
/**
* Full constructor.
* @param _evalFitness the fitness assignment strategy
* @param _evalDiversity the diversity assignment strategy
* @param _comparator the comparator (used to compare 2 individuals)
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoDiversityAssignment < MOEOT > & _evalDiversity, moeoComparator < MOEOT > & _comparator) :
evalFitness (_evalFitness), evalDiversity (_evalDiversity), comparator (_comparator)
{}
/**
* Constructor without comparator. A moeoFitThenDivComparator is used as default.
* @param _evalFitness the fitness assignment strategy
* @param _evalDiversity the diversity assignment strategy
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoDiversityAssignment < MOEOT > & _evalDiversity) :
evalFitness (_evalFitness), evalDiversity (_evalDiversity), comparator (*(new moeoFitnessThenDiversityComparator < MOEOT >))
{}
/**
* Constructor without comparator. A moeoFitThenDivComparator is used as default.
* @param _evalFitness the fitness assignment strategy
* @param _evalDiversity the diversity assignment strategy
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoDiversityAssignment < MOEOT > & _evalDiversity) :
evalFitness (_evalFitness), evalDiversity (_evalDiversity), comparator (*(new moeoFitnessThenDiversityComparator < MOEOT >))
{}
/**
* Constructor without moeoDiversityAssignement. A dummy diversity is used as default.
* @param _evalFitness the fitness assignment strategy
* @param _comparator the comparator (used to compare 2 individuals)
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoComparator < MOEOT > & _comparator) :
evalFitness (_evalFitness), evalDiversity (*(new moeoDummyDiversityAssignment < MOEOT >)), comparator (_comparator)
{}
/**
* Constructor without moeoDiversityAssignement. A dummy diversity is used as default.
* @param _evalFitness the fitness assignment strategy
* @param _comparator the comparator (used to compare 2 individuals)
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoComparator < MOEOT > & _comparator) :
evalFitness (_evalFitness), evalDiversity (*(new moeoDummyDiversityAssignment < MOEOT >)), comparator (_comparator)
{}
/**
* Constructor without moeoDiversityAssignement nor moeoComparator.
* A moeoFitThenDivComparator and a dummy diversity are used as default.
* @param _evalFitness the fitness assignment strategy
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness) :
evalFitness (_evalFitness), evalDiversity (*(new moeoDummyDiversityAssignment < MOEOT >)), comparator (*(new moeoFitnessThenDiversityComparator < MOEOT >))
{}
/**
* Constructor without moeoDiversityAssignement nor moeoComparator.
* A moeoFitThenDivComparator and a dummy diversity are used as default.
* @param _evalFitness the fitness assignment strategy
*/
moeoElitistReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness) :
evalFitness (_evalFitness), evalDiversity (*(new moeoDummyDiversityAssignment < MOEOT >)), comparator (*(new moeoFitnessThenDiversityComparator < MOEOT >))
{}
/**
* Replaces the first population by adding the individuals of the second one, sorting with a moeoComparator and resizing the whole population obtained.
* @param _parents the population composed of the parents (the population you want to replace)
* @param _offspring the offspring population
*/
void operator () (eoPop < MOEOT > &_parents, eoPop < MOEOT > &_offspring)
{
unsigned sz = _parents.size ();
// merges offspring and parents into a global population
_parents.reserve (_parents.size () + _offspring.size ());
copy (_offspring.begin (), _offspring.end (), back_inserter (_parents));
//remove the doubles in the whole pop
/****************************************************************************
eoRemoveDoubles < MOEOT > r;
r(_parents);
****************************************************************************/
// evaluates the fitness and the diversity of this global population
evalFitness (_parents);
evalDiversity (_parents);
// sorts the whole population according to the comparator
Cmp cmp(comparator);
std::sort(_parents.begin(), _parents.end(), cmp);
// finally, resize this global population
_parents.resize (sz);
// and clear the offspring population
_offspring.clear ();
}
/**
* Replaces the first population by adding the individuals of the second one, sorting with a moeoComparator and resizing the whole population obtained.
* @param _parents the population composed of the parents (the population you want to replace)
* @param _offspring the offspring population
*/
void operator () (eoPop < MOEOT > &_parents, eoPop < MOEOT > &_offspring)
{
unsigned sz = _parents.size ();
// merges offspring and parents into a global population
_parents.reserve (_parents.size () + _offspring.size ());
copy (_offspring.begin (), _offspring.end (), back_inserter (_parents));
//remove the doubles in the whole pop
/****************************************************************************
eoRemoveDoubles < MOEOT > r;
r(_parents);
****************************************************************************/
// evaluates the fitness and the diversity of this global population
evalFitness (_parents);
evalDiversity (_parents);
// sorts the whole population according to the comparator
Cmp cmp(comparator);
std::sort(_parents.begin(), _parents.end(), cmp);
// finally, resize this global population
_parents.resize (sz);
// and clear the offspring population
_offspring.clear ();
}
protected:
/** the fitness assignment strategy */
moeoFitnessAssignment < MOEOT > & evalFitness;
/** the diversity assignment strategy */
moeoDiversityAssignment < MOEOT > & evalDiversity;
/** the comparator (used to compare 2 individuals) */
moeoComparator < MOEOT > & comparator;
/** the fitness assignment strategy */
moeoFitnessAssignment < MOEOT > & evalFitness;
/** the diversity assignment strategy */
moeoDiversityAssignment < MOEOT > & evalDiversity;
/** the comparator (used to compare 2 individuals) */
moeoComparator < MOEOT > & comparator;
/**
* This class is used to compare solutions in order to sort the population.
*/
class Cmp
{
public:
/**
* Ctor.
* @param _comparator the comparator
*/
Cmp(moeoComparator < MOEOT > & _comparator) : comparator(_comparator)
{}
/**
* Returns true if _moeo1 is greater than _moeo2 according to the comparator
* _moeo1 the first individual
* _moeo2 the first individual
*/
bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
return comparator(_moeo1,_moeo2);
}
private:
/** the comparator */
moeoComparator < MOEOT > & comparator;
};
/**
* This class is used to compare solutions in order to sort the population.
*/
class Cmp
{
public:
/**
* Ctor.
* @param _comparator the comparator
*/
Cmp(moeoComparator < MOEOT > & _comparator) : comparator(_comparator)
{}
/**
* Returns true if _moeo1 is greater than _moeo2 according to the comparator
* _moeo1 the first individual
* _moeo2 the first individual
*/
bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2)
{
return comparator(_moeo1,_moeo2);
}
private:
/** the comparator */
moeoComparator < MOEOT > & comparator;
};
};

Some files were not shown because too many files have changed in this diff Show more