From 528a149107e2e97fa4c3c8fbfe8f26fa19826438 Mon Sep 17 00:00:00 2001 From: liefooga Date: Tue, 10 Apr 2007 13:34:32 +0000 Subject: [PATCH] BIG update git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@210 331e1502-861f-0410-8da2-ba01fb791d7f --- branches/paradiseo-moeo-1.0/src/MOEO.h | 6 +- .../src/do/{make_algo.h => make_algo_moeo.h} | 78 ++++-- .../src/do/make_checkpoint_moeo.h | 249 ++++++++++++++++++ .../src/do/make_continue_moeo.h | 142 ++++++++++ .../paradiseo-moeo-1.0/src/do/make_ls_moeo.h | 122 +++++++++ ...NormalizedSolutionVsSolutionBinaryMetric.h | 12 +- .../metric/moeoVectorVsSolutionBinaryMetric.h | 221 ---------------- branches/paradiseo-moeo-1.0/src/moeo | 30 ++- branches/paradiseo-moeo-1.0/src/moeoArchive.h | 45 +++- .../paradiseo-moeo-1.0/src/moeoCombinedLS.h | 22 +- .../paradiseo-moeo-1.0/src/moeoComparator.h | 51 +++- .../src/moeoCrowdingDiversityAssignment.h | 103 ++++++++ branches/paradiseo-moeo-1.0/src/moeoEasyEA.h | 112 ++++++++ .../src/moeoElitistReplacement.h | 43 ++- .../src/moeoEnvironmentalReplacement.h | 134 ++++++++++ ...FastNonDominatedSortingFitnessAssignment.h | 18 ++ .../src/moeoFitnessAssignment.h | 5 +- .../src/moeoIndicatorBasedFitnessAssignment.h | 198 ++++++++++++-- .../src/moeoIndicatorBasedLS.h | 210 +++++++++++++++ .../src/moeoIteratedIBMOLS.h | 218 +++++++++++++++ branches/paradiseo-moeo-1.0/src/moeoLS.h | 8 +- .../paradiseo-moeo-1.0/src/moeoMoveIncrEval.h | 12 + .../src/moeoObjectiveVector.h | 2 +- .../src/moeoObjectiveVectorComparator.h | 87 +++++- ...encePointIndicatorBasedFitnessAssignment.h | 102 +++++++ .../paradiseo-moeo-1.0/src/moeoReplacement.h | 3 +- .../src/moeoSelectFromPopAndArch.h | 4 +- 27 files changed, 1892 insertions(+), 345 deletions(-) rename branches/paradiseo-moeo-1.0/src/do/{make_algo.h => make_algo_moeo.h} (70%) mode change 100644 => 100755 create mode 100755 branches/paradiseo-moeo-1.0/src/do/make_checkpoint_moeo.h create mode 100755 branches/paradiseo-moeo-1.0/src/do/make_continue_moeo.h create mode 100755 branches/paradiseo-moeo-1.0/src/do/make_ls_moeo.h delete mode 100644 branches/paradiseo-moeo-1.0/src/metric/moeoVectorVsSolutionBinaryMetric.h create mode 100755 branches/paradiseo-moeo-1.0/src/moeoCrowdingDiversityAssignment.h create mode 100755 branches/paradiseo-moeo-1.0/src/moeoEasyEA.h create mode 100755 branches/paradiseo-moeo-1.0/src/moeoEnvironmentalReplacement.h create mode 100755 branches/paradiseo-moeo-1.0/src/moeoIndicatorBasedLS.h create mode 100755 branches/paradiseo-moeo-1.0/src/moeoIteratedIBMOLS.h create mode 100644 branches/paradiseo-moeo-1.0/src/moeoMoveIncrEval.h create mode 100755 branches/paradiseo-moeo-1.0/src/moeoReferencePointIndicatorBasedFitnessAssignment.h diff --git a/branches/paradiseo-moeo-1.0/src/MOEO.h b/branches/paradiseo-moeo-1.0/src/MOEO.h index c05ae9df5..8408677a5 100644 --- a/branches/paradiseo-moeo-1.0/src/MOEO.h +++ b/branches/paradiseo-moeo-1.0/src/MOEO.h @@ -32,7 +32,7 @@ * !!!!!!!!!!!!!!!!!!!!!!! */ template < class MOEOObjectiveVector, class MOEOFitness, class MOEODiversity > -class MOEO : public EO < MOEOFitness > +class MOEO : public EO < MOEOObjectiveVector > { public: @@ -115,7 +115,7 @@ public: { if ( invalidFitness() ) { - // throw std::runtime_error("invalid fitness"); + throw std::runtime_error("invalid fitness (MOEO)"); } return fitnessValue; } @@ -157,7 +157,7 @@ public: { if ( invalidDiversity() ) { - // throw std::runtime_error("invalid diversity"); + throw std::runtime_error("invalid diversity"); } return diversityValue; } diff --git a/branches/paradiseo-moeo-1.0/src/do/make_algo.h b/branches/paradiseo-moeo-1.0/src/do/make_algo_moeo.h old mode 100644 new mode 100755 similarity index 70% rename from branches/paradiseo-moeo-1.0/src/do/make_algo.h rename to branches/paradiseo-moeo-1.0/src/do/make_algo_moeo.h index 64973ae9c..892294dd7 --- a/branches/paradiseo-moeo-1.0/src/do/make_algo.h +++ b/branches/paradiseo-moeo-1.0/src/do/make_algo_moeo.h @@ -1,7 +1,7 @@ // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- //----------------------------------------------------------------------------- -// make_algo.h +// make_algo_moeo.h // (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 /* This library... @@ -10,10 +10,10 @@ */ //----------------------------------------------------------------------------- -#ifndef MAKE_ALGO_H_ -#define MAKE_ALGO_H_ +#ifndef MAKE_ALGO_MOEO_H_ +#define MAKE_ALGO_MOEO_H_ -#include +#include #include #include #include @@ -22,51 +22,71 @@ #include #include #include +#include #include #include #include +#include #include +#include #include #include #include #include #include +#include #include #include #include #include #include -#include /** * ... - * - * !!! eoEvalFunc => moeoEvalFunc - * !!! eoAlgo => moeoEA - * !!! ... */ template < class MOEOT > -eoAlgo < MOEOT > & do_make_algo(eoParser & _parser, eoState & _state, eoEvalFunc < MOEOT > & _eval, - eoContinue < MOEOT > & _continue, eoGenOp < MOEOT > & _op, moeoArchive < MOEOT > & _archive) +moeoEA < MOEOT > & do_make_algo_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 fitness assignment strategy */ string & fitnessParam = _parser.createParam(string("FastNonDominatedSorting"), "fitness", - "Fitness assignment strategy parameter: FastNonDominatedSorting, IndicatorBased...", 'F', "Evolution Engine").value(); + "Fitness assignment strategy parameter: FastNonDominatedSorting, IndicatorBased, ReferencePointIndicatorBased ...", 'F', + "Evolution Engine").value(); + string & indicatorParam = _parser.createParam(string("Epsilon"), "indicator", + "Binary indicator to use with the IndicatorBased assignment: 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("FastNonDominatedSorting")) { fitnessAssignment = new moeoFastNonDominatedSortingFitnessAssignment < MOEOT> (); } - /****************************************************************************************************************************/ else if (fitnessParam == string("IndicatorBased")) { - typedef typename MOEOT::ObjectiveVector ObjectiveVector; - moeoAdditiveEpsilonBinaryMetric < ObjectiveVector > * e = new moeoAdditiveEpsilonBinaryMetric < ObjectiveVector >; - moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > * metric = new moeoExponentialVectorVsSolutionBinaryMetric < ObjectiveVector> (e,0.001); - fitnessAssignment = new moeoIndicatorBasedFitnessAssignment < MOEOT> (metric); + // 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; @@ -76,10 +96,14 @@ eoAlgo < MOEOT > & do_make_algo(eoParser & _parser, eoState & _state, eoEvalFunc /* the diversity assignment strategy */ - string & diversityParam = _parser.createParam(string("Dummy"), "diversity", - "Diversity assignment strategy parameter: Dummy, ...", 'D', "Evolution Engine").value(); + string & diversityParam = _parser.createParam(string("Dummy"), "diversity", + "Diversity assignment strategy parameter: Dummy, Crowding, ...", 'D', "Evolution Engine").value(); moeoDiversityAssignment < MOEOT > * diversityAssignment; - if (diversityParam == string("Dummy")) + if (diversityParam == string("Crowding")) + { + diversityAssignment = new moeoCrowdingDiversityAssignment < MOEOT> (); + } + else if (diversityParam == string("Dummy")) { diversityAssignment = new moeoDummyDiversityAssignment < MOEOT> (); } @@ -113,7 +137,7 @@ eoAlgo < MOEOT > & do_make_algo(eoParser & _parser, eoState & _state, eoEvalFunc /* the selection strategy */ eoValueParam < eoParamParamType > & selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection", - "Selection strategy parameter: DetTour(T), StochTour(t), Roulette or Random", 'S', "Evolution Engine"); + "Selection strategy parameter: DetTour(T), StochTour(t) or Random", 'S', "Evolution Engine"); eoParamParamType & ppSelect = selectionParam.value(); moeoSelectOne < MOEOT > * select; if (ppSelect.first == string("DetTour")) @@ -167,12 +191,16 @@ eoAlgo < MOEOT > & do_make_algo(eoParser & _parser, eoState & _state, eoEvalFunc /* the replacement strategy */ string & replacementParam = _parser.createParam(string("Elitist"), "replacement", - "Replacement strategy parameter: Elitist or Generational", 'R', "Evolution Engine").value(); + "Replacement strategy parameter: 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> (); @@ -194,10 +222,10 @@ eoAlgo < MOEOT > & do_make_algo(eoParser & _parser, eoState & _state, eoEvalFunc eoGeneralBreeder < MOEOT > * breed = new eoGeneralBreeder < MOEOT > (*select, _op, offspringRateParam.value()); _state.storeFunctor(breed); // the eoEasyEA - eoAlgo < MOEOT > * algo = new eoEasyEA < MOEOT > (_continue, _eval, *breed, *replace); + moeoEA < MOEOT > * algo = new moeoEasyEA < MOEOT > (_continue, _eval, *breed, *replace, *fitnessAssignment, *diversityAssignment); _state.storeFunctor(algo); return *algo; } -#endif /*MAKE_ALGO_H_*/ +#endif /*MAKE_ALGO_MOEO_H_*/ diff --git a/branches/paradiseo-moeo-1.0/src/do/make_checkpoint_moeo.h b/branches/paradiseo-moeo-1.0/src/do/make_checkpoint_moeo.h new file mode 100755 index 000000000..5d9dfe77b --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/do/make_checkpoint_moeo.h @@ -0,0 +1,249 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_checkpoint_pareto.h +// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000 +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@inria.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _make_checkpoint_pareto_h +#define _make_checkpoint_pareto_h + +#include +#include + +#include "MOEO.h" +//#include "eoParetoFitness.h" +#include "eoEvalFuncCounter.h" +#include "utils/checkpointing" +#include "utils/selectors.h" + +// at the moment, in utils/make_help.cpp +// this should become some eoUtils.cpp with corresponding eoUtils.h +bool testDirRes(std::string _dirName, bool _erase); +/////////////////// The checkpoint and other I/O ////////////// + +/** + */ +template +eoCheckPoint& do_make_checkpoint_moeo(eoParser& _parser, eoState& _state, + eoEvalFuncCounter& _eval, eoContinue& _continue) +{ + // first, create a checkpoint from the eoContinue - and store in _state + eoCheckPoint & checkpoint = _state.storeFunctor(new eoCheckPoint(_continue)); + + /////// get number of obectives + unsigned nObj = EOT::ObjectiveVector::nObjectives(); + + /////////////////// + // Counters + ////////////////// + // is nb Eval to be used as counter? + bool useEval = _parser.getORcreateParam(true, "useEval", + "Use nb of eval. as counter (vs nb of gen.)", + '\0', "Output").value(); + + // Create anyway a generation-counter parameter WARNING: not stored anywhere!!! + eoValueParam *generationCounter = new eoValueParam(0, "Gen."); + // Create an incrementor (sub-class of eoUpdater). + eoIncrementor & increment = + _state.storeFunctor(new eoIncrementor(generationCounter->value()) ); + // Add it to the checkpoint, + checkpoint.add(increment); + + // dir for DISK output + std::string & dirName = _parser.getORcreateParam(std::string("Res"), "resDir", + "Directory to store DISK outputs", + '\0', "Output - Disk").value(); + // shoudl we empty it if exists + eoValueParam& eraseParam = _parser.getORcreateParam(true, "eraseDir", + "erase files in dirName if any", + '\0', "Output - Disk"); + bool dirOK = false; // not tested yet + + ///////////////////////////////////////// + // now some statistics on the population: + ///////////////////////////////////////// + /** + * existing stats for Pareto as of today, Jan. 31. 2002 + * + * eoSortedPopStat : whole population - type std::string (!!) + */ +/* + eoValueParam& fPlotParam + = _parser.getORcreateParam(eoParamParamType("1(0,1)"), "frontFileFrequency", + "File save frequency in objective spaces (std::pairs of comma-separated objectives " \ + "in 1 single parentheses std::pair)", + '\0', "Output - Disk"); + + bool boolGnuplot = _parser.getORcreateParam(false, "plotFront", + "Objective plots (requires corresponding files " \ + "- see frontFileFrequency", + '\0', "Output - Graphical").value(); + + eoParamParamType & fPlot = fPlotParam.value(); // std::pair > + unsigned frequency = atoi(fPlot.first.c_str()); + if (frequency) // something to plot + { + unsigned nbPlot = fPlot.second.size(); + if ( nbPlot % 2 ) // odd! + throw std::runtime_error("Odd number of front description in make_checkpoint_pareto"); + + // only create the necessary stats + std::vector bStat(nObj, false); // track of who's already there + std::vector* > theStats(nObj); + + // first create the stats + for (unsigned i=0; i* fStat; + if (!bStat[obj1]) { // not already there: create it + std::ostringstream os; + os << "Obj. " << obj1 << std::ends; + fStat = new eoMOFitnessStat(obj1, os.str().c_str()); + _state.storeFunctor(fStat); + bStat[obj1]=true; + theStats[obj1]=fStat; + checkpoint.add(*fStat); + } + if (!bStat[obj2]) { // not already there: create it + std::ostringstream os; + os << "Obj. " << obj2 << std::ends; + fStat = new eoMOFitnessStat(obj2, os.str().c_str()); + _state.storeFunctor(fStat); + bStat[obj2]=true; + theStats[obj2]=fStat; + checkpoint.add(*fStat); + } + + // then the fileSnapshots + std::ostringstream os; + os << "Front." << obj1 << "." << obj2 << "." << std::ends; + eoFileSnapshot& snapshot = _state.storeFunctor( + new eoFileSnapshot(dirName, frequency, os.str().c_str())); + checkpoint.add(snapshot); + + snapshot.add(*theStats[obj1]); + snapshot.add(*theStats[obj2]); + + // and create the gnuplotter from the fileSnapshot + if(boolGnuplot) + { + eoGnuplot1DSnapshot & plotSnapshot = _state.storeFunctor(new + eoGnuplot1DSnapshot(snapshot)); + plotSnapshot.setPointSize(3); + checkpoint.add(plotSnapshot); + } + } + } +*/ + // Dump of the whole population + //----------------------------- +/* + bool printPop = _parser.getORcreateParam(false, "printPop", + "Print sorted pop. every gen.", + '\0', "Output").value(); + eoSortedPopStat * popStat; + if ( printPop ) // we do want pop dump + { + std::cout << "On cree printpop\n"; + popStat = & _state.storeFunctor(new eoSortedPopStat); + // add it to the checkpoint + checkpoint.add(*popStat); + } +*/ + /////////////// + // The monitors + /////////////// +/* + // do we want an eoStdoutMonitor? + bool needStdoutMonitor = printPop ; // only this one at the moment + + // The Stdout monitor will print parameters to the screen ... + if ( needStdoutMonitor ) + { + eoStdoutMonitor & monitor = _state.storeFunctor(new eoStdoutMonitor(false)); + + // when called by the checkpoint (i.e. at every generation) + checkpoint.add(monitor); + + // the monitor will output a series of parameters: add them + monitor.add(*generationCounter); + if (useEval) // we want nb of evaluations + monitor.add(_eval); + if ( printPop) + monitor.add(*popStat); + } +*/ + + ////////////////////////////////// + // State savers + ////////////////////////////// + + // feed the state to state savers + // save state every N generation + eoValueParam& 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 ); +#ifdef _MSVC + std::string stmp = dirName + "\generations"; +#else + std::string stmp = dirName + "/generations"; +#endif + eoCountedStateSaver *stateSaver1 = new eoCountedStateSaver(freq, _state, stmp); + _state.storeFunctor(stateSaver1); + checkpoint.add(*stateSaver1); + } + + // save state every T seconds + eoValueParam& 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 + +#ifdef _MSVC + std::string stmp = dirName + "\time"; +#else + std::string stmp = dirName + "/time"; +#endif + eoTimedStateSaver *stateSaver2 = new eoTimedStateSaver(saveTimeIntervalParam.value(), _state, stmp); + _state.storeFunctor(stateSaver2); + checkpoint.add(*stateSaver2); + } + + + // and that's it for the (control and) output + return checkpoint; +} + +#endif diff --git a/branches/paradiseo-moeo-1.0/src/do/make_continue_moeo.h b/branches/paradiseo-moeo-1.0/src/do/make_continue_moeo.h new file mode 100755 index 000000000..e083581ca --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/do/make_continue_moeo.h @@ -0,0 +1,142 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_continue_pareto.h +// (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2000 +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@inria.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _make_continue_pareto_h +#define _make_continue_pareto_h + +/* +Contains the templatized version of parser-based choice of stopping criterion +for Pareto optimization (e.g. no "... without improvement" criterion +It can then be instantiated, and compiled on its own for a given EOType +(see e.g. in dir ga, ga.cpp) +*/ + +// Continuators - all include eoContinue.h +#include +#include +#include +#include +#include +#ifndef _MSC_VER +#include // CtrlC handling (using 2 global variables!) +#endif + + // also need the parser and param includes +#include +#include + + +/////////////////// helper function //////////////// +template +eoCombinedContinue * make_combinedContinue(eoCombinedContinue *_combined, eoContinue *_cont) +{ + if (_combined) // already exists + _combined->add(*_cont); + else + _combined = new eoCombinedContinue(*_cont); + return _combined; +} + +///////////// The make_continue function +template +eoContinue & do_make_continue_moeo(eoParser& _parser, eoState& _state, eoEvalFuncCounter & _eval) +{ + //////////// Stopping criterion /////////////////// + // the combined continue - to be filled + eoCombinedContinue *continuator = NULL; + + // for each possible criterion, check if wanted, otherwise do nothing + + // First the eoGenContinue - need a default value so you can run blind + // but we also need to be able to avoid it <--> 0 + eoValueParam& maxGenParam = _parser.createParam(unsigned(100), "maxGen", "Maximum number of generations () = none)",'G',"Stopping criterion"); + + if (maxGenParam.value()) // positive: -> define and store + { + eoGenContinue *genCont = new eoGenContinue(maxGenParam.value()); + _state.storeFunctor(genCont); + // and "add" to combined + continuator = make_combinedContinue(continuator, genCont); + } + + +/**************************/ + eoValueParam& maxEvalParam + = _parser.getORcreateParam((unsigned long)0, "maxEval", + "Maximum number of evaluations (0 = none)", + 'E', "Stopping criterion"); + if (maxEvalParam.value()) // positive: -> define and store + { + eoEvalContinue *evalCont = new eoEvalContinue(_eval, maxEvalParam.value()); + _state.storeFunctor(evalCont); + // and "add" to combined + continuator = make_combinedContinue(continuator, evalCont); + } +/**************************/ + + + +/**************************/ + eoValueParam& 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 *timeCont = new eoTimeContinue(maxTimeParam.value()); + _state.storeFunctor(timeCont); + // and "add" to combined + continuator = make_combinedContinue(continuator, timeCont); + } +/**************************/ + + + +#ifndef _MSC_VER + // the CtrlC interception (Linux only I'm afraid) + eoCtrlCContinue *ctrlCCont; + eoValueParam& ctrlCParam = _parser.createParam(true, "CtrlC", "Terminate current generation upon Ctrl C",'C', "Stopping criterion"); + if (_parser.isItThere(ctrlCParam)) + { + ctrlCCont = new eoCtrlCContinue; + // store + _state.storeFunctor(ctrlCCont); + // add to combinedContinue + continuator = make_combinedContinue(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 + return *continuator; +} + +#endif diff --git a/branches/paradiseo-moeo-1.0/src/do/make_ls_moeo.h b/branches/paradiseo-moeo-1.0/src/do/make_ls_moeo.h new file mode 100755 index 000000000..f5976747f --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/do/make_ls_moeo.h @@ -0,0 +1,122 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_ls_moeo.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MAKE_LS_MOEO_H_ +#define MAKE_LS_MOEO_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * ... + */ +template < class MOEOT, class Move > +moeoLS < MOEOT, eoPop & > & do_make_ls_moeo ( + eoParser & _parser, + eoState & _state, + moeoEvalFunc < 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); + + + + + 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 & > * 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); + + + return *ls; + +} + +#endif /*MAKE_LS_MOEO_H_*/ diff --git a/branches/paradiseo-moeo-1.0/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h b/branches/paradiseo-moeo-1.0/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h index 8ca0fa9c1..08fae6af3 100644 --- a/branches/paradiseo-moeo-1.0/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h +++ b/branches/paradiseo-moeo-1.0/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h @@ -27,7 +27,7 @@ class moeoNormalizedSolutionVsSolutionBinaryMetric : public moeoSolutionVsSoluti { public: - /** very small value to avoid the extreme case where the min bound = the max bound */ + /** very small value to avoid the extreme case where the min bound == the max bound */ const static double tiny = 1e-6; @@ -46,15 +46,13 @@ public: * _max upper bound * _obj the objective index */ - virtual void setup(double _min, double _max, unsigned _obj) + void setup(double _min, double _max, unsigned _obj) { - /* - if (min = max) + if (_min == _max) { - min -= tiny; - max += tiny; + _min -= tiny; + _max += tiny; } - */ bounds[_obj] = eoRealInterval(_min, _max); } diff --git a/branches/paradiseo-moeo-1.0/src/metric/moeoVectorVsSolutionBinaryMetric.h b/branches/paradiseo-moeo-1.0/src/metric/moeoVectorVsSolutionBinaryMetric.h deleted file mode 100644 index 3e847ccb6..000000000 --- a/branches/paradiseo-moeo-1.0/src/metric/moeoVectorVsSolutionBinaryMetric.h +++ /dev/null @@ -1,221 +0,0 @@ -// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - -//----------------------------------------------------------------------------- -// moeoVectorVsSolutionBinaryMetric.h -// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 -/* - This library... - - Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr - */ -//----------------------------------------------------------------------------- - -#ifndef MOEOVECTORVSSOLUTIONBINARYMETRIC_H_ -#define MOEOVECTORVSSOLUTIONBINARYMETRIC_H_ - -#include -#include - - -/** - * Base class for binary metrics dedicated to the performance comparison between a Pareto set (a vector of objective vectors) and a single solution's objective vector. - */ -template < class ObjectiveVector, class R > -class moeoVectorVsSolutionBinaryMetric : public moeoBinaryMetric < const std::vector < ObjectiveVector > &, const ObjectiveVector &, R > -{ -public: - - /** - * Default ctor - * @param _metric the binary metric for the performance comparison between two solutions's objective vectors using normalized values - */ - moeoVectorVsSolutionBinaryMetric(moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * _metric) : metric(_metric) - {} - - /** - * Returns the value of the metric comparing the set _v to an objective vector _o - * _v a vector of objective vectors - * _o an objective vector - */ - double operator()(const std::vector < ObjectiveVector > & _v, const ObjectiveVector & _o) - { - // 1 - set the bounds for every objective - setBounds(_v, _o); - // 2 - compute every indicator value - computeValues(_v, _o); - // 3 - resulting value - return result(); - } - - -protected: - - /** the binary metric for the performance comparison between two solutions's objective vectors using normalized values */ - moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * metric; - /** the indicator values : values[i] = I(_v[i], _o) */ - vector < double > values; - - - /** - * Sets the bounds for every objective using the min and the max value - * _v a vector of objective vectors - * _o an objective vector - */ - void setBounds(const std::vector < ObjectiveVector > & _v, const ObjectiveVector & _o) - { - double min, max; - for (unsigned i=0; i & _v, const ObjectiveVector & _o) - { - values.clear(); - values.resize(_v.size()); - for (unsigned i=0; i<_v.size(); i++) - { - values[i] = (*metric)(_v[i], _o); - } - } - - - /** - * Returns the global result that combines the I-values - */ - virtual double result() = 0; - -}; - - -/** - * Minimum version of binary metric dedicated to the performance comparison between a vector of objective vectors and a single solution's objective vector. - */ -template < class ObjectiveVector > -class moeoMinimumVectorVsSolutionBinaryMetric : public moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > -{ -public: - - /** - * Ctor - * @param _metric the binary metric for the performance comparison between two solutions's objective vectors using normalized values - */ - moeoMinimumVectorVsSolutionBinaryMetric(moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * _metric) : moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > (_metric) - {} - - -private: - - /** the indicator values : values[i] = I(_v[i], _o) */ - using moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double >::values; - - - /** - * Returns the minimum binary indicator values computed - */ - double result() - { - return *std::min_element(values.begin(), values.end()); - } - -}; - - -/** - * Additive version of binary metric dedicated to the performance comparison between a vector of objective vectors and a single solution's objective vector. - */ -template < class ObjectiveVector > -class moeoAdditiveVectorVsSolutionBinaryMetric : public moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > -{ -public: - - /** - * Ctor - * @param _metric the binary metric for the performance comparison between two solutions's objective vectors using normalized values - */ - moeoAdditiveVectorVsSolutionBinaryMetric(moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * _metric) : moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > (_metric) - {} - - -private: - - /** the indicator values : values[i] = I(_v[i], _o) */ - using moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double >::values; - - - /** - * Returns the sum of the binary indicator values computed - */ - double result() - { - double result = 0; - for (unsigned i=0; i -class moeoExponentialVectorVsSolutionBinaryMetric : public moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > -{ -public: - - /** - * Ctor - * @param _metric the binary metric for the performance comparison between two solutions's objective vectors using normalized values - */ - moeoExponentialVectorVsSolutionBinaryMetric(moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * _metric, const double _kappa) : - moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > (_metric), kappa(_kappa) - {} - - -private: - - /** scaling factor kappa */ - double kappa; - /** the indicator values : values[i] = I(_v[i], _o) */ - using moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double >::values; - - - /** - * Returns a kind of sum of the binary indicator values computed that amplifies the influence of dominating objective vectors over dominated ones - */ - double result() - { - double result = 0; - for (unsigned i=0; i -#include -#include -#include -#include -#include -#include +#include #include #include #include #include #include +#include +#include #include #include +#include +#include #include +//#include #include #include #include -#include +//#include +#include +//#include +//#include #include #include -#include #include -#include +#include #include -#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include #endif /*MOEO_*/ diff --git a/branches/paradiseo-moeo-1.0/src/moeoArchive.h b/branches/paradiseo-moeo-1.0/src/moeoArchive.h index 09fff58bb..df21ae1ba 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoArchive.h +++ b/branches/paradiseo-moeo-1.0/src/moeoArchive.h @@ -63,7 +63,7 @@ public: if ( comparator(operator[](i).fitness(), _objectiveVector) ) { return true; - } + } } return false; } @@ -77,7 +77,7 @@ public: { for (unsigned i = 0; i & _arch) + { + for (unsigned i=0; i & comparator; - /** A moeoObjectiveVectorComparator based on Pareto dominance (used as default) */ + /** A moeoObjectiveVectorComparator based on Pareto dominance (used as default) */ moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator; - + }; #endif /*MOEOARCHIVE_H_ */ diff --git a/branches/paradiseo-moeo-1.0/src/moeoCombinedLS.h b/branches/paradiseo-moeo-1.0/src/moeoCombinedLS.h index 59f380f3d..21c99f4ce 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoCombinedLS.h +++ b/branches/paradiseo-moeo-1.0/src/moeoCombinedLS.h @@ -14,15 +14,14 @@ #define MOEOCOMBINEDLS_H_ #include -#include #include /** * 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 moeoCombinedLS : public moeoLS < MOEOT > +template < class MOEOT, class Type > +class moeoCombinedLS : public moeoLS < MOEOT, Type > { public: @@ -31,18 +30,18 @@ public: * @param _eval the full evaluator of a solution * @param _first_mols the first multi-objective local search to add */ - moeoCombinedLS(moeoEvalFunc < MOEOT > & _eval, moeoLS < MOEOT > & _first_mols) : eval (_eval) + 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 > & _mols) + void add(moeoLS < MOEOT, Type > & _mols) { - combinedMOLS.push_back(& _mols); + combinedLS.push_back(& _mols); } /** @@ -51,20 +50,17 @@ public: * @param _moeo the solution * @param _arch the archive of non-dominated solutions */ - void operator () (const MOEOT & _moeo, moeoArchive < MOEOT > & _arch) + void operator () (Type _type, moeoArchive < MOEOT > & _arch) { - eval(const_cast < MOEOT & > (_moeo)); for (unsigned i=0; i operator()(_moeo, _arch); + combinedLS[i] -> operator()(_type, _arch); } private: - /** the full evaluator of a solution */ - moeoEvalFunc < MOEOT > & eval; /** the vector that contains the combined LS */ - std::vector< moeoLS < MOEOT > * > combinedLS; + std::vector< moeoLS < MOEOT, Type > * > combinedLS; }; diff --git a/branches/paradiseo-moeo-1.0/src/moeoComparator.h b/branches/paradiseo-moeo-1.0/src/moeoComparator.h index 21f2d355b..67e66eae9 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoComparator.h +++ b/branches/paradiseo-moeo-1.0/src/moeoComparator.h @@ -31,16 +31,51 @@ class moeoObjectiveComparator : public moeoComparator < MOEOT > { public: /** - * Returns true if _moeo1 is smaller than _moeo2 on the first objective, then on the second, and so on + * 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(); + return _moeo1.objectiveVector() > _moeo2.objectiveVector(); } }; +/** + * Functor allowing to compare two solutions according to one objective. + */ +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]; + } + +private: + unsigned obj; + +}; + /** * Functor allowing to compare two solutions according to their fitness values, then according to their diversity values. @@ -50,7 +85,7 @@ class moeoFitnessThenDiversityComparator : public moeoComparator < MOEOT > { public: /** - * Returns true if _moeo1 is smaller than _moeo2 according to their fitness values, then according to their diversity values + * 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 */ @@ -58,11 +93,11 @@ public: { if (_moeo1.fitness() == _moeo2.fitness()) { - return _moeo1.diversity() < _moeo2.diversity(); + return _moeo1.diversity() > _moeo2.diversity(); } else { - return _moeo1.fitness() < _moeo2.fitness(); + return _moeo1.fitness() > _moeo2.fitness(); } } }; @@ -76,7 +111,7 @@ class moeoDiversityThenFitnessComparator : public moeoComparator < MOEOT > { public: /** - * Returns true if _moeo1 is smaller than _moeo2 according to their diversity values, then according to their fitness values + * 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 */ @@ -84,11 +119,11 @@ public: { if (_moeo1.diversity() == _moeo2.diversity()) { - return _moeo1.fitness() < _moeo2.fitness(); + return _moeo1.fitness() > _moeo2.fitness(); } else { - return _moeo1.diversity() < _moeo2.diversity(); + return _moeo1.diversity() > _moeo2.diversity(); } } }; diff --git a/branches/paradiseo-moeo-1.0/src/moeoCrowdingDiversityAssignment.h b/branches/paradiseo-moeo-1.0/src/moeoCrowdingDiversityAssignment.h new file mode 100755 index 000000000..cfcef8e8f --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/moeoCrowdingDiversityAssignment.h @@ -0,0 +1,103 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// moeoCrowdingDiversityAssignment.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MOEOCROWDINGDISTANCEASSIGNMENT_H_ +#define MOEOCROWDINGDISTANCEASSIGNMENT_H_ + +#include +#include +#include + +/** + * 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. + */ +template < class MOEOT > +class moeoCrowdingDiversityAssignment : public moeoDiversityAssignment < MOEOT > +{ +public: + + + /** Infinity value */ + double inf ()const + { + return std::numeric_limits::max(); + } + + + /** + * ... + * @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); + } + } + + + + +private: + + /** the objective vector type of the solutions */ + typedef typename MOEOT::ObjectiveVector ObjectiveVector; + + + /** + * ... + * @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 comp(obj); + // sort + std::sort(_pop.begin(), _pop.end(), comp); + // min & max + min = _pop[0].objectiveVector()[obj]; + max = _pop[_pop.size()-1].objectiveVector()[obj]; + _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); + } + } + } + +}; + +#endif /*MOEOCROWDINGDIVERSITYASSIGNMENT_H_*/ diff --git a/branches/paradiseo-moeo-1.0/src/moeoEasyEA.h b/branches/paradiseo-moeo-1.0/src/moeoEasyEA.h new file mode 100755 index 000000000..579f8b053 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/moeoEasyEA.h @@ -0,0 +1,112 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +#ifndef _MOEOEASYEA_H +#define _MOEOEASYEA_H + +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template < class MOEOT > +class moeoEasyEA: public moeoEA < MOEOT > +{ +public: + + /** Ctor taking a breed and merge */ + moeoEasyEA( + eoContinue& _continuator, + eoEvalFunc& _eval, + eoBreed& _breed, + eoReplacement& _replace, + moeoFitnessAssignment& _fitnessEval, + moeoDiversityAssignment& _diversityEval, + bool _evalFitAndDivBeforeSelection = false + ) : continuator(_continuator), + eval (_eval), + loopEval(_eval), + popEval(loopEval), + breed(_breed), + replace(_replace), + fitnessEval(_fitnessEval), + diversityEval(_diversityEval), + evalFitAndDivBeforeSelection(_evalFitAndDivBeforeSelection) + {} + + /// Apply a few generation of evolution to the population. + virtual void operator()(eoPop& _pop) + { + eoPop offspring, empty_pop; + popEval(empty_pop, _pop); // A first eval of pop. + fitnessEval(_pop); + diversityEval(_pop); + bool firstTime = true; + do + { + try + { + unsigned pSize = _pop.size(); + offspring.clear(); // new offspring + + /************************************/ + if ( evalFitAndDivBeforeSelection && (! firstTime) ) + { + fitnessEval(_pop); + diversityEval(_pop); + } + else + { + firstTime = false; + } + /************************************/ + + 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 : + + eoContinue& continuator; + eoEvalFunc & eval ; + eoPopLoopEval loopEval; + eoPopEvalFunc& popEval; + eoBreed& breed; + eoReplacement& replace; + /** the fitness assignment strategy */ + moeoFitnessAssignment < MOEOT > & fitnessEval; + /** the diversity assignment strategy */ + moeoDiversityAssignment < MOEOT > & diversityEval; + /** */ + bool evalFitAndDivBeforeSelection; + +}; + +//----------------------------------------------------------------------------- + +#endif diff --git a/branches/paradiseo-moeo-1.0/src/moeoElitistReplacement.h b/branches/paradiseo-moeo-1.0/src/moeoElitistReplacement.h index cb9aaa9be..899e3d596 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoElitistReplacement.h +++ b/branches/paradiseo-moeo-1.0/src/moeoElitistReplacement.h @@ -17,7 +17,9 @@ #include #include #include - +/////////////////////////////////////// +#include +/////////////////////////////////////// /** * Elitist replacement strategy for multi-objective optimization. @@ -35,8 +37,8 @@ public: 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 @@ -49,7 +51,8 @@ public: moeoFitnessThenDiversityComparator < MOEOT > &fitThenDivComparator; comparator = fitThenDivComparator; } - + + /** * Constructor without moeoDiversityAssignement. A dummy diversity is used as default. * @param _evalFitness the fitness assignment strategy @@ -62,7 +65,8 @@ public: moeoDummyDiversityAssignment < MOEOT > &dummyDiversityAssignment; evalDiversity = dummyDiversityAssignment; } - + + /** * Constructor without moeoDiversityAssignement nor moeoComparator. * A moeoFitThenDivComparator and a dummy diversity are used as default. @@ -78,6 +82,7 @@ public: comparator = fitThenDivComparator; } + /** * 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) @@ -89,16 +94,20 @@ public: // 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 - - /*************************************************************************/ - moeoFitnessThenDiversityComparator < MOEOT > comp; - std::sort (_parents.begin (), _parents.end (), comp); - /*************************************************************************/ - + Cmp cmp(comparator); + std::sort(_parents.begin(), _parents.end(), cmp); // finally, resize this global population _parents.resize (sz); // and clear the offspring population @@ -115,6 +124,18 @@ protected: /** the comparator (used to compare 2 individuals) */ moeoComparator < MOEOT > & comparator; + class Cmp + { + public: + Cmp(moeoComparator < MOEOT > & _comparator) : comparator(_comparator) {} + bool operator()(const MOEOT & a, const MOEOT & b) + { + return comparator(a,b); + } + private: + moeoComparator < MOEOT > & comparator; + }; + }; #endif /*MOEOELITISTREPLACEMENT_H_ */ diff --git a/branches/paradiseo-moeo-1.0/src/moeoEnvironmentalReplacement.h b/branches/paradiseo-moeo-1.0/src/moeoEnvironmentalReplacement.h new file mode 100755 index 000000000..8316fd3c7 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/moeoEnvironmentalReplacement.h @@ -0,0 +1,134 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// moeoEnvironmentalReplacement.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MOEOENVIRONMENTALREPLACEMENT_H_ +#define MOEOENVIRONMENTALREPLACEMENT_H_ + +#include +#include +#include +#include + + +/** + * ??? + */ +template < class MOEOT > class moeoEnvironmentalReplacement:public moeoReplacement < MOEOT > +{ +public: + + /** + * Full constructor. + * @param _evalFitness the fitness assignment strategy + * @param _evalDiversity the diversity assignment strategy + * @param _comparator the comparator (used to compare 2 individuals) + */ + moeoEnvironmentalReplacement (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 + */ + moeoEnvironmentalReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoDiversityAssignment < MOEOT > & _evalDiversity) : + evalFitness (_evalFitness), evalDiversity (_evalDiversity) + { + // a moeoFitThenDivComparator is used as default + moeoFitnessThenDiversityComparator < MOEOT > &fitThenDivComparator; + comparator = fitThenDivComparator; + } + + + /** + * 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) + */ + moeoEnvironmentalReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness, moeoComparator < MOEOT > & _comparator) : + evalFitness (_evalFitness), comparator (_comparator) + { + // a dummy diversity is used as default + moeoDummyDiversityAssignment < MOEOT > &dummyDiversityAssignment; + evalDiversity = dummyDiversityAssignment; + } + + /** + * Constructor without moeoDiversityAssignement nor moeoComparator. + * A moeoFitThenDivComparator and a dummy diversity are used as default. + * @param _evalFitness the fitness assignment strategy + */ + moeoEnvironmentalReplacement (moeoFitnessAssignment < MOEOT > & _evalFitness) : evalFitness (_evalFitness) + { + // a dummy diversity is used as default + moeoDummyDiversityAssignment < MOEOT > & dummyDiversityAssignment; + evalDiversity = dummyDiversityAssignment; + // a moeoFitThenDivComparator is used as default + moeoFitnessThenDiversityComparator < MOEOT > & fitThenDivComparator; + comparator = fitThenDivComparator; + } + + /** + * 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)); + // evaluates the fitness and the diversity of this global population + evalFitness (_parents); + evalDiversity (_parents); + // remove individuals 1 by 1 and update the fitness values + Cmp cmp(comparator); + MOEOT worst; + while (_parents.size() > sz) + { + std::sort (_parents.begin(), _parents.end(), cmp); + worst = _parents[_parents.size()-1]; + _parents.resize(_parents.size()-1); + evalFitness.updateByDeleting(_parents, worst); + } + // 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; + + class Cmp + { + public: + Cmp(moeoComparator < MOEOT > & _comparator) : comparator(_comparator) {} + bool operator()(const MOEOT & a, const MOEOT & b) + { + return comparator(a,b); + } + private: + moeoComparator < MOEOT > & comparator; + }; + +}; + +#endif /*MOEOENVIRONMENTALREPLACEMENT_H_ */ diff --git a/branches/paradiseo-moeo-1.0/src/moeoFastNonDominatedSortingFitnessAssignment.h b/branches/paradiseo-moeo-1.0/src/moeoFastNonDominatedSortingFitnessAssignment.h index 624df8c73..19caa2aa2 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoFastNonDominatedSortingFitnessAssignment.h +++ b/branches/paradiseo-moeo-1.0/src/moeoFastNonDominatedSortingFitnessAssignment.h @@ -64,9 +64,24 @@ public: // problem with the number of objectives throw std::runtime_error("Problem with the number of objectives in moeoFastNonDominatedSortingFitnessAssignment"); } + // a higher fitness is better, so the values need to be inverted + double max = _pop[0].fitness(); + for (unsigned i=1 ; i<_pop.size() ; i++) + { + max = std::max(max, _pop[i].fitness()); + } + for (unsigned i=0 ; i<_pop.size() ; i++) + { + _pop[i].fitness(max - _pop[i].fitness()); + } } + void updateByDeleting(eoPop < MOEOT > & _pop, MOEOT & _moeo) + { + cout << "WARNING : not yet implemented in NDSortingFitAss" << endl; + } + private: /** the objective vector type of the solutions */ @@ -83,11 +98,14 @@ private: */ void oneObjective (eoPop < MOEOT > & _pop) { + // TO DO ! + /* std::sort(_pop.begin(), _pop.end(), objComparator); for (unsigned i=0; i<_pop.size(); i++) { _pop[i].fitness(i+1); } + */ } diff --git a/branches/paradiseo-moeo-1.0/src/moeoFitnessAssignment.h b/branches/paradiseo-moeo-1.0/src/moeoFitnessAssignment.h index 5c4e5c68b..6c07dcbd0 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoFitnessAssignment.h +++ b/branches/paradiseo-moeo-1.0/src/moeoFitnessAssignment.h @@ -21,7 +21,10 @@ */ template < class MOEOT > class moeoFitnessAssignment : public eoUF < eoPop < MOEOT > &, void > -{}; +{ +public: + virtual void updateByDeleting(eoPop < MOEOT > & _pop, MOEOT & _moeo) = 0; +}; /** diff --git a/branches/paradiseo-moeo-1.0/src/moeoIndicatorBasedFitnessAssignment.h b/branches/paradiseo-moeo-1.0/src/moeoIndicatorBasedFitnessAssignment.h index 82f6e76f3..3f0f42ab9 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoIndicatorBasedFitnessAssignment.h +++ b/branches/paradiseo-moeo-1.0/src/moeoIndicatorBasedFitnessAssignment.h @@ -13,14 +13,14 @@ #ifndef MOEOINDICATORBASEDFITNESSASSIGNMENT_H_ #define MOEOINDICATORBASEDFITNESSASSIGNMENT_H_ +#include #include #include #include #include -#include /** - * + * Default is exponential */ template < class MOEOT > class moeoIndicatorBasedFitnessAssignment : public moeoFitnessAssignment < MOEOT > @@ -30,47 +30,193 @@ public: /** The type of objective vector */ typedef typename MOEOT::ObjectiveVector ObjectiveVector; - - /** - * Default ctor - * @param ... - */ - moeoIndicatorBasedFitnessAssignment(moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > * _metric) : metric(_metric) - {} - - /** * Ctor * @param ... - */ - moeoIndicatorBasedFitnessAssignment(moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * _solutionVsSolutionMetric, const double _kappa)// : metric(moeoExponentialVectorVsSolutionBinaryMetric < ObjectiveVector > (_solutionVsSolutionMetric, _kappa)) - { - metric = new moeoExponentialVectorVsSolutionBinaryMetric < ObjectiveVector > (_solutionVsSolutionMetric, _kappa); - } + */ + moeoIndicatorBasedFitnessAssignment(moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * _metric, const double _kappa) : metric(_metric), kappa(_kappa) + {} /** - * + * */ void operator()(eoPop < MOEOT > & _pop) { - eoPop < MOEOT > tmp_pop; - moeoConvertPopToObjectiveVectors < MOEOT > convertor; - for (unsigned i=0; i<_pop.size() ; i++) + // 1 - setting of the bounds + setup(_pop); + // 2 - computing every indicator values + computeValues(_pop); + // 3 - setting fitnesses + setFitnesses(_pop); + } + + +///////////////////////////////////////////////////////////////////// + + +// A SIMPLIFIER ! => utiliser la fonction d'en dessous ;-) + void updateByDeleting(eoPop < MOEOT > & _pop, MOEOT & _moeo) + { + vector < double > v; + v.resize(_pop.size()); + for (unsigned i=0; i<_pop.size(); i++) { - tmp_pop.clear(); - tmp_pop = _pop; - tmp_pop.erase(tmp_pop.begin() + i); - _pop[i].fitness((*metric) (convertor(tmp_pop), _pop[i].objectiveVector())); + v[i] = (*metric)(_moeo.objectiveVector(), _pop[i].objectiveVector()); + } + for (unsigned i=0; i<_pop.size(); i++) + { + _pop[i].fitness( _pop[i].fitness() + exp(-v[i]/kappa) ); } } + void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec) + { + vector < double > v; + v.resize(_pop.size()); + for (unsigned i=0; i<_pop.size(); i++) + { + v[i] = (*metric)(_objVec, _pop[i].objectiveVector()); + } + for (unsigned i=0; i<_pop.size(); i++) + { + _pop[i].fitness( _pop[i].fitness() + exp(-v[i]/kappa) ); + } + } -private: - moeoVectorVsSolutionBinaryMetric < ObjectiveVector, double > * metric; + // IDEM ! + void updateByAdding(eoPop < MOEOT > & _pop, MOEOT & _moeo) + { + vector < double > v; + // update every fitness values to take the new individual into account + v.resize(_pop.size()); + for (unsigned i=0; i<_pop.size(); i++) + { + v[i] = (*metric)(_moeo.objectiveVector(), _pop[i].objectiveVector()); + } + for (unsigned i=0; i<_pop.size(); i++) + { + _pop[i].fitness( _pop[i].fitness() - exp(-v[i]/kappa) ); + } + // compute the fitness of the new individual + v.clear(); + v.resize(_pop.size()); + for (unsigned i=0; i<_pop.size(); i++) + { + v[i] = (*metric)(_pop[i].objectiveVector(), _moeo.objectiveVector()); + } + double fitness = 0; + for (unsigned i=0; i & _pop, ObjectiveVector & _objVec) + { + vector < double > v; + // update every fitness values to take the new individual into account + v.resize(_pop.size()); + for (unsigned i=0; i<_pop.size(); i++) + { + v[i] = (*metric)(_objVec, _pop[i].objectiveVector()); + } + for (unsigned i=0; i<_pop.size(); i++) + { + _pop[i].fitness( _pop[i].fitness() - exp(-v[i]/kappa) ); + } + // compute the fitness of the new individual + v.clear(); + v.resize(_pop.size()); + for (unsigned i=0; i<_pop.size(); i++) + { + v[i] = (*metric)(_pop[i].objectiveVector(), _objVec); + } + double result = 0; + for (unsigned i=0; i * metric; + double kappa; + std::vector < std::vector > values; + + + /** + * Sets the bounds for every objective using the min and the max value for every objective vector of _pop + * @param _pop the population + */ + void setup(const eoPop < MOEOT > & _pop) + { + double min, max; + for (unsigned i=0; i & _pop) + { + values.clear(); + values.resize(_pop.size()); + for (unsigned i=0; i<_pop.size(); i++) + { + values[i].resize(_pop.size()); + for (unsigned j=0; j<_pop.size(); j++) + { + if (i != j) + { + values[i][j] = (*metric)(_pop[i].objectiveVector(), _pop[j].objectiveVector()); + } + } + } + } + + void setFitnesses(eoPop < MOEOT > & _pop) + { + for (unsigned i=0; i<_pop.size(); i++) + { + _pop[i].fitness(computeFitness(i)); + } + } + + double computeFitness(const unsigned _idx) + { + double result = 0; + for (unsigned i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Indicator-Based Multi-Objective Local Search (IBMOLS) as described in + * Basseur M., Burke K. : "Indicator-Based Multi-Objective Local Search" (2007). + */ +template < class MOEOT, class Move > +class moeoIndicatorBasedLS : public moeoLS < MOEOT, eoPop < MOEOT > & > +{ +public: + + /** The type of objective vector */ + typedef typename MOEOT::ObjectiveVector ObjectiveVector; + + + /** + * Ctor. + * @param _moveInit the move initializer + * @param _nextMove the neighborhood explorer + * @param _eval the full evaluation + * @param _moveIncrEval the incremental evaluation + * @param _fitnessAssignment the fitness assignment strategy + * @param _continuator the stopping criteria + */ + moeoIndicatorBasedLS( + moMoveInit < Move > & _moveInit, + moNextMove < Move > & _nextMove, + moeoEvalFunc < MOEOT > & _eval, + moeoMoveIncrEval < Move > & _moveIncrEval, + moeoIndicatorBasedFitnessAssignment < MOEOT > & _fitnessAssignment, + eoContinue < MOEOT > & _continuator + ) : + moveInit(_moveInit), + nextMove(_nextMove), + eval(_eval), + moveIncrEval(_moveIncrEval), + fitnessAssignment (_fitnessAssignment), + continuator (_continuator) + {} + + + /** + * Apply the local search until a local archive does not change or + * another stopping criteria is met and update the archive _arch with new non-dominated solutions. + * @param _pop the initial population + * @param _arch the (updated) archive + */ + void operator() (eoPop < MOEOT > & _pop, moeoArchive < MOEOT > & _arch) + { + // evaluation of the objective values + for (unsigned i=0; i<_pop.size(); i++) + { + eval(_pop[i]); + } + // fitness assignment for the whole population + fitnessAssignment(_pop); + // creation of a local archive + moeoArchive < MOEOT > archive; + // creation of another local archive (for the stopping criteria) + moeoArchive < MOEOT > previousArchive; + // update the archive with the initial population + archive.update(_pop); +unsigned counter=0; + do + { + previousArchive.update(archive); + oneStep(_pop); + archive.update(_pop); +counter++; + } while ( (! archive.equals(previousArchive)) && (continuator(_arch)) ); + _arch.update(archive); +cout << "\t=> " << counter << " step(s)" << endl; + } + + +private: + + /** the move initializer */ + moMoveInit < Move > & moveInit; + /** the neighborhood explorer */ + moNextMove < Move > & nextMove; + /** the full evaluation */ + eoEvalFunc < MOEOT > & eval; + /** the incremental evaluation */ + moeoMoveIncrEval < Move > & moveIncrEval; + /** the fitness assignment strategy */ + moeoIndicatorBasedFitnessAssignment < MOEOT > & fitnessAssignment; + /** the stopping criteria */ + eoContinue < MOEOT > & continuator; + + + /** + * Apply one step of the local search to the population _pop + * @param _pop the population + */ + void oneStep (eoPop < MOEOT > & _pop) + { + // the move + Move move; + // the objective vector and the fitness of the current solution + ObjectiveVector x_objVec; + double x_fitness; + // the index, the objective vector and the fitness of the worst solution in the population (-1 implies that the worst is the newly created one) + int worst_idx; + ObjectiveVector worst_objVec; + double worst_fitness; + // the index current of the current solution to be explored + unsigned i=0; + // initilization of the move for the first individual + moveInit(move, _pop[i]); + while (i<_pop.size() && continuator(_pop)) + { + // x = one neigbour of pop[i] + // evaluate x in the objective space + x_objVec = moveIncrEval(move, _pop[i]); + // update every fitness values to take x into account and compute the fitness of x + x_fitness = fitnessAssignment.updateByAdding(_pop, x_objVec); + // who is the worst individual ? + worst_idx = -1; + worst_objVec = x_objVec; + worst_fitness = x_fitness; + for (unsigned j=0; j<_pop.size(); j++) + { + if (_pop[j].fitness() < worst_fitness) + { + worst_idx = j; + worst_objVec = _pop[j].objectiveVector(); + worst_fitness = _pop[j].fitness(); + } + } + // the worst solution is the new one + if (worst_idx == -1) + { + // if all its neighbours have been explored, + // let's explore the neighborhoud of the next individual + if (! nextMove(move, _pop[i])) + { + i++; + if (i<_pop.size()) + { + // initilization of the move for the next individual + moveInit(move, _pop[i]); + } + } + } + // the worst solution is located before _pop[i] + else if (worst_idx <= i) + { + // the new solution takes place insteed of _pop[worst_idx] + _pop[worst_idx] = _pop[i]; + move(_pop[worst_idx]); + _pop[worst_idx].objectiveVector(x_objVec); + _pop[worst_idx].fitness(x_fitness); + // let's explore the neighborhoud of the next individual + i++; + if (i<_pop.size()) + { + // initilization of the move for the next individual + moveInit(move, _pop[i]); + } + } + // the worst solution is located after _pop[i] + else if (worst_idx > i) + { + // the new solution takes place insteed of _pop[i+1] and _pop[worst_idx] is deleted + _pop[worst_idx] = _pop[i+1]; + _pop[i+1] = _pop[i]; + move(_pop[i+1]); + _pop[i+1].objectiveVector(x_objVec); + _pop[i+1].fitness(x_fitness); + // do not explore the neighbors of the new solution immediately + i = i+2; + if (i<_pop.size()) + { + // initilization of the move for the next individual + moveInit(move, _pop[i]); + } + } + // update fitness values + fitnessAssignment.updateByDeleting(_pop, worst_objVec); + } + } + +}; + +#endif /*MOEOINDICATORBASEDLS_H_*/ diff --git a/branches/paradiseo-moeo-1.0/src/moeoIteratedIBMOLS.h b/branches/paradiseo-moeo-1.0/src/moeoIteratedIBMOLS.h new file mode 100755 index 000000000..cc950033f --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/moeoIteratedIBMOLS.h @@ -0,0 +1,218 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// moeoIteratedIBMOLS.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + This library... + + Contact: paradiseo-help@lists.gforge.inria.fr, http://paradiseo.gforge.inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef MOEOITERATEDIBMOLS_H_ +#define MOEOITERATEDIBMOLS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include + + + +/** + * Iterated version of IBMOLS as described in + * Basseur M., Burke K. : "Indicator-Based Multi-Objective Local Search" (2007). + */ +template < class MOEOT, class Move > +class moeoIteratedIBMOLS : public moeoLS < MOEOT, eoPop < MOEOT > & > +{ +public: + + /** The type of objective vector */ + typedef typename MOEOT::ObjectiveVector ObjectiveVector; + + + /** + * Ctor. + * @param _moveInit the move initializer + * @param _nextMove the neighborhood explorer + * @param _eval the full evaluation + * @param _moveIncrEval the incremental evaluation + * @param _fitnessAssignment the fitness assignment strategy + * @param _continuator the stopping criteria + * @param _monOp the monary operator + * @param _randomMonOp the random monary operator (or random initializer) + * @param _nNoiseIterations the number of iterations to apply the random noise + */ + moeoIteratedIBMOLS( + moMoveInit < Move > & _moveInit, + moNextMove < Move > & _nextMove, + moeoEvalFunc < MOEOT > & _eval, + moeoMoveIncrEval < Move > & _moveIncrEval, + moeoIndicatorBasedFitnessAssignment < MOEOT > & _fitnessAssignment, + eoContinue < MOEOT > & _continuator, + eoMonOp < MOEOT > & _monOp, + eoMonOp < MOEOT > & _randomMonOp, + unsigned _nNoiseIterations=1 + ) : + ibmols(_moveInit, _nextMove, _eval, _moveIncrEval, _fitnessAssignment, _continuator), + eval(_eval), + continuator(_continuator), + monOp(_monOp), + randomMonOp(_randomMonOp), + nNoiseIterations(_nNoiseIterations) + {} + + + /** + * Apply the local search iteratively until the stopping criteria is met. + * @param _pop the initial population + * @param _arch the (updated) archive + */ + void operator() (eoPop < MOEOT > & _pop, moeoArchive < MOEOT > & _arch) + { + + _arch.update(_pop); +cout << endl << endl << "***** IBMOLS 1" << endl; +unsigned counter = 2; + ibmols(_pop, _arch); + while (continuator(_arch)) + { + // generate new solutions from the archive + generateNewSolutions(_pop, _arch); +cout << endl << endl << "***** IBMOLS " << counter++ << endl; + // apply the local search (the global archive is updated in the sub-function) + ibmols(_pop, _arch); + } + + } + + +private: + + /** the stopping criteria */ + eoContinue < MOEOT > & continuator; + /** the local search to iterate */ + moeoIndicatorBasedLS < MOEOT, Move > ibmols; + /** the full evaluation */ + moeoEvalFunc < MOEOT > & eval; + /** the monary operator */ + eoMonOp < MOEOT > & monOp; + /** the random monary operator (or random initializer) */ + eoMonOp < MOEOT > & randomMonOp; + /** the number of iterations to apply the random noise */ + unsigned nNoiseIterations; + + + /** + * Creates new population randomly initialized and/or initialized from the archive _arch. + * @param _pop the output population + * @param _arch the archive + */ + void generateNewSolutions(eoPop < MOEOT > & _pop, const moeoArchive < MOEOT > & _arch) + { + // shuffle vector for the random selection of individuals + vector shuffle; + shuffle.resize(std::max(_pop.size(), _arch.size())); + // init shuffle + for (unsigned i=0; i gen; + std::random_shuffle(shuffle.begin(), shuffle.end(), gen); + // start the creation of new solutions + for (unsigned i=0; i<_pop.size(); i++) + { + if (shuffle[i] < _arch.size()) + // the given archive contains the individual i + { + // add it to the resulting pop + _pop[i] = _arch[shuffle[i]]; + // then, apply the operator nIterationsNoise times + for (unsigned j=0; j & _pop, const moeoArchive < MOEOT > & _arch) + { + // here, we must have a QuadOp ! + //eoQuadOp < MOEOT > quadOp; + rsCrossQuad quadOp; + // shuffle vector for the random selection of individuals + vector shuffle; + shuffle.resize(_arch.size()); + // init shuffle + for (unsigned i=0; i gen; + std::random_shuffle(shuffle.begin(), shuffle.end(), gen); + // start the creation of new solutions + unsigned i=0; + while ((i<_pop.size()-1) && (i<_arch.size()-1)) + { + _pop[i] = _arch[shuffle[i]]; + _pop[i+1] = _arch[shuffle[i+1]]; + // then, apply the operator nIterationsNoise times + for (unsigned j=0; j -class moeoLS: public eoBF < const MOEOT &, moeoArchive < MOEOT > &, void > -{}; +template < class MOEOT, class Type > +class moeoLS: public eoBF < Type, moeoArchive < MOEOT > &, void > +{}; #endif /*MOEOLS_H_*/ diff --git a/branches/paradiseo-moeo-1.0/src/moeoMoveIncrEval.h b/branches/paradiseo-moeo-1.0/src/moeoMoveIncrEval.h new file mode 100644 index 000000000..6ecb0b635 --- /dev/null +++ b/branches/paradiseo-moeo-1.0/src/moeoMoveIncrEval.h @@ -0,0 +1,12 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +#ifndef _MOEOMOVEINCREVAL_H +#define _MOEOMOVEINCREVAL_H + +#include + +template < class Move > +class moeoMoveIncrEval : public eoBF < const Move &, const typename Move::EOType &, typename Move::EOType::ObjectiveVector > +{}; + +#endif diff --git a/branches/paradiseo-moeo-1.0/src/moeoObjectiveVector.h b/branches/paradiseo-moeo-1.0/src/moeoObjectiveVector.h index 229dfb0f3..262fa7352 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoObjectiveVector.h +++ b/branches/paradiseo-moeo-1.0/src/moeoObjectiveVector.h @@ -207,7 +207,7 @@ std::ostream & operator<<(std::ostream & _os, const moeoObjectiveVectorDouble < { for (unsigned i=0; i<_objectiveVector.size(); i++) { - _os << _objectiveVector[i] << ' '; + _os << _objectiveVector[i] << '\t'; } return _os; } diff --git a/branches/paradiseo-moeo-1.0/src/moeoObjectiveVectorComparator.h b/branches/paradiseo-moeo-1.0/src/moeoObjectiveVectorComparator.h index 9ec09b85b..78c681543 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoObjectiveVectorComparator.h +++ b/branches/paradiseo-moeo-1.0/src/moeoObjectiveVectorComparator.h @@ -73,7 +73,92 @@ public: } } return dom; - } + } + +}; + + +/** + * This functor class allows to compare 2 objective vectors according to g-dominance. + * The concept of g-dominance as been introduced in: + * J. Molina, L. V. Santana, A. G. Hernandez-Diaz, C. A. Coello Coello, R. Caballero, + * "g-dominance: Reference point based dominance" (2007) + */ +template < class ObjectiveVector > +class moeoGDominanceObjectiveVectorComparator : public moeoObjectiveVectorComparator < ObjectiveVector > +{ +public: + + /** + * Ctor. + * @param _ref the reference point + */ + moeoGDominanceObjectiveVectorComparator(ObjectiveVector _ref) : ref(_ref) + {} + + + /** + * Returns true if _objectiveVector1 g-dominates _objectiveVector2. + * @param _objectiveVector1 the first objective vector + * @param _objectiveVector2 the second objective vector + */ + bool operator()(const ObjectiveVector & _objectiveVector1, const ObjectiveVector & _objectiveVector2) + { + unsigned flag1 = flag(_objectiveVector1); + unsigned flag2 = flag(_objectiveVector2); + if (flag1==0) + { + // cannot dominate + return false; + } + else if ( (flag1==1) && (flag2==0) ) + { + // dominates + return true; + } + else // (flag1==1) && (flag2==1) + { + // both are on the good region, so let's use the classical Pareto dominance + return paretoComparator(_objectiveVector1, _objectiveVector2); + } + } + + +private: + + /** the reference point */ + ObjectiveVector ref; + /** Pareto comparator */ + moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator; + + + /** + * Returns the flag of _objectiveVector according to the reference point + * @param _objectiveVector the first objective vector + */ + unsigned flag(const ObjectiveVector & _objectiveVector) + { + unsigned result=1; + for (unsigned i=0; i ref[i]) + { + result=0; + } + } + if (result==0) + { + result=1; + for (unsigned i=0; i +#include +#include +#include + +/** + * + */ +template < class MOEOT > +class moeoReferencePointIndicatorBasedFitnessAssignment : public moeoFitnessAssignment < MOEOT > +{ +public: + + /** The type of objective vector */ + typedef typename MOEOT::ObjectiveVector ObjectiveVector; + + /** + * Ctor + * @param ... + */ + moeoReferencePointIndicatorBasedFitnessAssignment + ( + const ObjectiveVector _refPoint, + moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * _metric + + ) : + refPoint(_refPoint), + metric(_metric) + {} + + + /** + * NE CALCULER LE FITNESS D'UNE SOL QUE SI INVALID() (ATTENTION BOUNDS !) + */ + void operator()(eoPop < MOEOT > & _pop) + { + // 1 - setting of the bounds + setup(_pop); + // 2 - setting fitnesses + setFitnesses(_pop); + } + + void updateByDeleting(eoPop < MOEOT > & _pop, MOEOT & _moeo) + { + // nothing to do ;-) + } + + +protected: + moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > * metric; + ObjectiveVector refPoint; + + + /** + * Sets the bounds for every objective using the min and the max value for every objective vector of _pop (and the reference point) + * @param _pop the population + */ + void setup(const eoPop < MOEOT > & _pop) + { + double min, max; + for (unsigned i=0; i & _pop) + { + for (unsigned i=0; i<_pop.size(); i++) + { + //_pop[i].fitness( (*metric)(refPoint, _pop[i].objectiveVector()) ); + _pop[i].fitness(- (*metric)(_pop[i].objectiveVector(), refPoint) ); + } + } + +}; + +#endif /*MOEOREFERENCEPOINTINDICATORBASEDFITNESSASSIGNMENT_H_*/ diff --git a/branches/paradiseo-moeo-1.0/src/moeoReplacement.h b/branches/paradiseo-moeo-1.0/src/moeoReplacement.h index aa0631754..fb856383b 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoReplacement.h +++ b/branches/paradiseo-moeo-1.0/src/moeoReplacement.h @@ -19,6 +19,7 @@ * Replacement strategy for multi-objective optimization. */ template < class MOEOT > -class moeoReplacement : public eoReplacement < MOEOT > {}; +class moeoReplacement : public eoReplacement < MOEOT > +{}; #endif /*MOEOREPLACEMENT_H_*/ diff --git a/branches/paradiseo-moeo-1.0/src/moeoSelectFromPopAndArch.h b/branches/paradiseo-moeo-1.0/src/moeoSelectFromPopAndArch.h index 954e9b85a..d91b8a291 100644 --- a/branches/paradiseo-moeo-1.0/src/moeoSelectFromPopAndArch.h +++ b/branches/paradiseo-moeo-1.0/src/moeoSelectFromPopAndArch.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include /** * Elitist selection process that consists in choosing individuals in the archive as well as in the current population. @@ -82,7 +82,7 @@ private: /** The ratio of selected individuals from the population*/ double ratioFromPop; /** A random selection operator (used as default for archSelectOne) */ - moeoRandomSelectOne< MOEOT > randomSelectOne; + moeoRandomSelect < MOEOT > randomSelectOne; };