# make_algo_pareto.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // make_algo_pareto.h
    00005 // (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2002
    00006 /*
    00007     This library is free software; you can redistribute it and/or
    00008     modify it under the terms of the GNU Lesser General Public
    00009     License as published by the Free Software Foundation; either
    00010     version 2 of the License, or (at your option) any later version.
    00011
    00012     This library is distributed in the hope that it will be useful,
    00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015     Lesser General Public License for more details.
    00016
    00017     You should have received a copy of the GNU Lesser General Public
    00018     License along with this library; if not, write to the Free Software
    00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00020
    00021     Contact: todos@geneura.ugr.es, http://geneura.ugr.es
    00022              Marc.Schoenauer@inria.fr
    00023              mkeijzer@dhi.dk
    00024  */
    00025 //-----------------------------------------------------------------------------
    00026
    00027 #ifndef _make_algo_pareto_h
    00028 #define _make_algo_pareto_h
    00029
    00030 #include "utils/eoData.h"     // for eo_is_a_rate
    00031 // everything tha's needed for the algorithms - SCALAR fitness
    00032
    00033 // Selection
    00034 // the eoSelectOne's
    00035 #include "eoSelectFromWorth.h"
    00036 #include "eoNDSorting.h"
    00037
    00038 // Breeders
    00039 #include "eoGeneralBreeder.h"
    00040
    00041 // Replacement - at the moment limited to eoNDPlusReplacement, locally defined
    00042 #include "eoReplacement.h"
    00043
    00044 template <class EOT, class WorthT = double>
    00045 class eoNDPlusReplacement : public eoReplacement<EOT>
    00046 {
    00047 public:
    00048   eoNDPlusReplacement(eoPerf2Worth<EOT, WorthT>& _perf2worth) : perf2worth(_perf2worth) {}
    00049
    00050   struct WorthPair : public std::pair<WorthT, const EOT*>
    00051   {
    00052     bool operator<(const WorthPair& other) const { return other.first < this->first; }
    00053   };
    00054
    00055   void operator()(eoPop<EOT>& _parents, eoPop<EOT>& _offspring)
    00056   {
    00057     unsigned sz = _parents.size();
    00058     _parents.reserve(_parents.size() + _offspring.size());
    00059     copy(_offspring.begin(), _offspring.end(), back_inserter(_parents));
    00060
    00061     // calculate worths
    00062     perf2worth(_parents);
    00063     perf2worth.sort_pop(_parents);
    00064     perf2worth.resize(_parents, sz);
    00065
    00066     _offspring.clear();
    00067   }
    00068
    00069 private :
    00070   eoPerf2Worth<EOT, WorthT>& perf2worth;
    00071 };
    00072
    00073
    00074 // Algorithm (only this one needed)
    00075 #include "eoEasyEA.h"
    00076
    00077   // also need the parser and param includes
    00078 #include "utils/eoParser.h"
    00079 #include "utils/eoState.h"
    00080
    00081
    00082 /*
    00083  * This function builds the algorithm (i.e. selection and replacement)
    00084  *      from existing continue (or checkpoint) and operators
    00085  *
    00086  * It uses a parser (to get user parameters) and a state (to store the memory)
    00087  * the last argument is an individual, needed for 2 reasons
    00088  *     it disambiguates the call after instanciations
    00089  *     some operator might need some private information about the indis
    00090  *
    00091  * This is why the template is the complete EOT even though only the fitness
    00092  * is actually templatized here
    00093 */
    00094
    00095 template <class EOT>
    00096 eoAlgo<EOT> & do_make_algo_pareto(eoParser& _parser, eoState& _state, eoEvalFunc<EOT>& _eval, eoContinue<EOT>& _continue, eoGenOp<EOT>& _op)
    00097 {
    00098   // the selection
    00099   std::string & selStr = _parser.createParam(std::string("NSGA-II"), "selCrit", "Pareto Selection Criterion: NSGA, NSGA-II, ParetoRanking", 'S', "Evolution Engine").value();
    00100   double nicheSize = _parser.createParam(1.0, "nicheSize", "Size of niche for NSGA-I", '\0', "Evolution Engine").value();
    00101   eoPerf2Worth<EOT, double> *p2w;
    00102   if ( (selStr == std::string("NSGA")) || (selStr == std::string("NSGA-I") ) )
    00103     p2w = new eoNDSorting_I<EOT>(nicheSize);
    00104   else   if (selStr == std::string("NSGA-II"))
    00105     p2w = new eoNDSorting_II<EOT>();
    00106   else   if (selStr == std::string("ParetoRanking"))
    00107     {
    00108       eoDominanceMap<EOT>&  dominance = _state.storeFunctor(new eoDominanceMap<EOT>);
    00109     p2w = new eoParetoRanking<EOT>(dominance);
    00110     }
    00111
    00112   _state.storeFunctor(p2w);
    00113
    00114   // now the selector (from p2w) - cut-and-pasted from make_algo_scalar!
    00115   // only all classes are now ...FromWorth ...
    00116   // only the ranking is not re-implemented (yet?)
    00117   eoValueParam<eoParamParamType>& selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection", "Selection: Roulette, DetTour(T), StochTour(t) or Random", 'S', "Evolution Engine");
    00118
    00119   eoParamParamType & ppSelect = selectionParam.value(); // std::pair<std::string,std::vector<std::string> >
    00120
    00121   eoSelectOne<EOT>* select ;
    00122   if (ppSelect.first == std::string("DetTour"))
    00123   {
    00124     unsigned detSize;
    00125
    00126     if (!ppSelect.second.size())   // no parameter added
    00127       {
    00128         std::cerr << "WARNING, no parameter passed to DetTour, using 2" << std::endl;
    00129         detSize = 2;
    00130         // put back 2 in parameter for consistency (and status file)
    00131         ppSelect.second.push_back(std::string("2"));
    00132       }
    00133     else          // parameter passed by user as DetTour(T)
    00134       detSize = atoi(ppSelect.second[0].c_str());
    00135     select = new eoDetTournamentWorthSelect<EOT>(*p2w, detSize);
    00136   }
    00137   else if (ppSelect.first == std::string("StochTour"))
    00138     {
    00139       double p;
    00140       if (!ppSelect.second.size())   // no parameter added
    00141         {
    00142           std::cerr << "WARNING, no parameter passed to StochTour, using 1" << std::endl;
    00143           p = 1;
    00144           // put back p in parameter for consistency (and status file)
    00145           ppSelect.second.push_back(std::string("1"));
    00146         }
    00147       else        // parameter passed by user as DetTour(T)
    00148         p = atof(ppSelect.second[0].c_str());
    00149
    00150       select = new eoStochTournamentWorthSelect<EOT>(*p2w, p);
    00151     }
    00152 //   else if (ppSelect.first == std::string("Sequential")) // one after the other
    00153 //     {
    00154 //       bool b;
    00155 //       if (ppSelect.second.size() == 0)   // no argument -> default = ordered
    00156 //      {
    00157 //        b=true;
    00158 //        // put back in parameter for consistency (and status file)
    00159 //        ppSelect.second.push_back(std::string("ordered"));
    00160 //      }
    00161 //       else
    00162 //      b = !(ppSelect.second[0] == std::string("unordered"));
    00163 //       select = new eoSequentialWorthSelect<EOT>(b);
    00164 //     }
    00165   else if (ppSelect.first == std::string("Roulette")) // no argument (yet)
    00166     {
    00167       select = new eoRouletteWorthSelect<EOT>(*p2w);
    00168     }
    00169   else if (ppSelect.first == std::string("Random")) // no argument, no perf2Worth
    00170     {
    00171       select = new eoRandomSelect<EOT>;
    00172     }
    00173   else
    00174     {
    00175       std::string stmp = std::string("Invalid selection: ") + ppSelect.first;
    00176       throw std::runtime_error(stmp.c_str());
    00177     }
    00178
    00179   _state.storeFunctor(select);
    00180
    00181
    00182   // the number of offspring
    00183     eoValueParam<eoHowMany>& offspringRateParam =  _parser.createParam(eoHowMany(1.0), "nbOffspring", "Nb of offspring (percentage or absolute)", 'O', "Evolution Engine");
    00184
    00185   // the replacement
    00186     // actually limited to eoNDPlusReplacement
    00187   eoReplacement<EOT> & replace = _state.storeFunctor(
    00188            new eoNDPlusReplacement<EOT, double>(*p2w)
    00189            );
    00190
    00191   // the general breeder
    00192   eoGeneralBreeder<EOT> *breed =
    00193     new eoGeneralBreeder<EOT>(*select, _op, offspringRateParam.value());
    00194   _state.storeFunctor(breed);
    00195
    00196   // now the eoEasyEA
    00197   eoAlgo<EOT> *algo = new eoEasyEA<EOT>(_continue, _eval, *breed, replace);
    00198   _state.storeFunctor(algo);
    00199   // that's it!
    00200   return *algo;
    00201 }
    00202
    00203 #endif