make_algo_easea.h

00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // make_algo_easea.h
00005 // (c) Marc Schoenauer and Pierre Collet, 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: Pierre.Collet@polytechnique.fr
00022              Marc.Schoenauer@polytechnique.fr
00023              mkeijzer@dhi.dk
00024  */
00025 //-----------------------------------------------------------------------------
00026 
00027 #ifndef _make_algo_easea_h
00028 #define _make_algo_easea_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 <eoRandomSelect.h>
00036 #include <eoSequentialSelect.h>
00037 #include <eoDetTournamentSelect.h>
00038 #include <eoProportionalSelect.h>
00039 #include <eoFitnessScalingSelect.h>
00040 #include <eoRankingSelect.h>
00041 #include <eoStochTournamentSelect.h>
00042 // #include <eoSelect.h>    included in all others
00043 
00044 // Breeders
00045 #include <eoGeneralBreeder.h>
00046 
00047 // Replacement
00048 #include "make_general_replacement.h"
00049 #include "eoMGGReplacement.h"
00050 #include "eoG3Replacement.h"
00051 
00052 
00053 // Algorithm (only this one needed)
00054 #include <eoEasyEA.h>
00055 
00056   // also need the parser and param includes
00057 #include <utils/eoParser.h>
00058 #include <utils/eoState.h>
00059 
00060 
00061 /*
00062  * This function builds the algorithm (i.e. selection and replacement)
00063  *      from existing continue (or checkpoint) and operators
00064  *
00065  * It uses a parser (to get user parameters) and a state (to store the memory)
00066  * the last argument is an individual, needed for 2 reasons
00067  *     it disambiguates the call after instanciations
00068  *     some operator might need some private information about the indis
00069  *
00070  * This is why the template is the complete EOT even though only the fitness
00071  * is actually templatized here
00072 */
00073 
00074 template <class EOT>
00075 eoAlgo<EOT> & do_make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<EOT>& _eval, eoContinue<EOT>& _continue, eoGenOp<EOT>& _op)
00076 {
00077   // the selection
00078   eoValueParam<eoParamParamType>& selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection", "Selection: Roulette, Ranking(p,e), DetTour(T), StochTour(t), Sequential(ordered/unordered) or EliteSequentialSelect", 'S', "Evolution Engine");
00079 
00080   eoParamParamType & ppSelect = selectionParam.value(); // std::pair<std::string,std::vector<std::string> >
00081 
00082   eoSelectOne<EOT>* select ;
00083   if (ppSelect.first == std::string("DetTour")) 
00084   {
00085     unsigned detSize;
00086 
00087     if (!ppSelect.second.size())   // no parameter added
00088       {
00089         std::cerr << "WARNING, no parameter passed to DetTour, using 2" << std::endl;
00090         detSize = 2;
00091         // put back 2 in parameter for consistency (and status file)
00092         ppSelect.second.push_back(std::string("2"));
00093       }
00094     else          // parameter passed by user as DetTour(T)
00095       detSize = atoi(ppSelect.second[0].c_str());
00096     select = new eoDetTournamentSelect<EOT>(detSize);
00097   }
00098   else if (ppSelect.first == std::string("StochTour"))
00099     {
00100       double p;
00101       if (!ppSelect.second.size())   // no parameter added
00102         {
00103           std::cerr << "WARNING, no parameter passed to StochTour, using 1" << std::endl;
00104           p = 1;
00105           // put back p in parameter for consistency (and status file)
00106           ppSelect.second.push_back(std::string("1"));
00107         }
00108       else        // parameter passed by user as DetTour(T)
00109         p = atof(ppSelect.second[0].c_str());
00110       
00111       select = new eoStochTournamentSelect<EOT>(p);
00112     }
00113   else if (ppSelect.first == std::string("Ranking"))
00114     {
00115       double p,e;
00116       if (ppSelect.second.size()==2)   // 2 parameters: pressure and exponent
00117         {
00118           p = atof(ppSelect.second[0].c_str());
00119           e = atof(ppSelect.second[1].c_str());
00120         }
00121       else if (ppSelect.second.size()==1)   // 1 parameter: pressure 
00122         {
00123           std::cerr << "WARNING, no exponent to Ranking, using 1" << std::endl;
00124           e = 1;
00125           ppSelect.second.push_back(std::string("1"));
00126           p = atof(ppSelect.second[0].c_str());
00127         }
00128       else // no parameters ... or garbage
00129         {
00130           std::cerr << "WARNING, no parameter to Ranking, using (2,1)" << std::endl;
00131           p=2;
00132           e=1;
00133           // put back in parameter for consistency (and status file)
00134           ppSelect.second.resize(2); // just in case
00135           ppSelect.second[0] = (std::string("2"));
00136           ppSelect.second[1] = (std::string("1"));
00137         }
00138       // check for authorized values
00139       // pressure in (0,1]
00140       if ( (p<=1) || (p>2) )
00141         {
00142           std::cerr << "WARNING, selective pressure must be in (1,2] in Ranking, using 2\n";
00143           p=2;
00144           ppSelect.second[0] = (std::string("2"));
00145         }
00146       // exponent >0
00147       if (e<=0)
00148         {
00149           std::cerr << "WARNING, exponent must be positive in Ranking, using 1\n";
00150           e=1;
00151           ppSelect.second[1] = (std::string("1"));
00152         }
00153       // now we're OK
00154       eoPerf2Worth<EOT> & p2w = _state.storeFunctor( new eoRanking<EOT>(p,e) );
00155       select = new eoRouletteWorthSelect<EOT>(p2w);
00156     }
00157   else if (ppSelect.first == std::string("Sequential")) // one after the other
00158     {
00159       bool b;
00160       if (ppSelect.second.size() == 0)   // no argument -> default = ordered
00161         {
00162           b=true;
00163           // put back in parameter for consistency (and status file)
00164           ppSelect.second.push_back(std::string("ordered"));
00165         }
00166       else
00167         b = !(ppSelect.second[0] == std::string("unordered"));
00168       select = new eoSequentialSelect<EOT>(b);
00169     }
00170   else if (ppSelect.first == std::string("EliteSequential")) // Best first, one after the other in random order afterwards
00171     {
00172       select = new eoEliteSequentialSelect<EOT>;
00173     }
00174   else if (ppSelect.first == std::string("Roulette")) // no argument (yet)
00175     {
00176       select = new eoProportionalSelect<EOT>;
00177     }
00178   else if (ppSelect.first == std::string("Random")) // no argument
00179     {
00180       select = new eoRandomSelect<EOT>;
00181     }
00182   else
00183     {
00184       std::string stmp = std::string("Invalid selection: ") + ppSelect.first;
00185       throw std::runtime_error(stmp.c_str());
00186     }
00187 
00188   _state.storeFunctor(select);
00189 
00190   // the number of offspring 
00191     eoValueParam<eoHowMany>& offspringRateParam =  _parser.createParam(eoHowMany(1.0), "nbOffspring", "Nb of offspring (percentage or absolute)", 'O', "Evolution Engine");
00192 
00194   // the replacement
00196 
00225   eoParamParamType & replacementParam = _parser.createParam(eoParamParamType("General"), "replacement", "Type of replacement: General, or Generational, ESComma, ESPlus, SSGA(T), EP(T), G3, MGG(T)", '\0', "Evolution Engine").value();
00226   // the pointer
00227   eoReplacement<EOT> * ptReplace;
00228 
00229   // first, separate G3 and MGG
00230   // maybe one day we have a common class - but is it really necessary???
00231   if (replacementParam.first == std::string("G3"))
00232     {
00233     // reduce the parents: by default, survive parents = -2 === 2 parents die
00234     eoHowMany surviveParents =  _parser.createParam(eoHowMany(-2,false), "surviveParents", "Nb of surviving parents (percentage or absolute)", '\0', "Evolution Engine / Replacement").value();
00235     // at the moment, this is the only argument
00236     ptReplace = new eoG3Replacement<EOT>(-surviveParents);    // must receive nb of eliminated parets!
00237     _state.storeFunctor(ptReplace);
00238     }
00239   else  if (replacementParam.first == std::string("MGG"))
00240     {
00241       float t;
00242       unsigned tSize;
00243     // reduce the parents: by default, survive parents = -2 === 2 parents die
00244     eoHowMany surviveParents =  _parser.createParam(eoHowMany(-2,false), "surviveParents", "Nb of surviving parents (percentage or absolute)", '\0', "Evolution Engine / Replacement").value();
00245     // the tournament size
00246     if (!replacementParam.second.size())   // no parameter added
00247       {
00248         std::cerr << "WARNING, no parameter passed to MGG replacement, using 2" << std::endl;
00249         tSize = 2;
00250         // put back 2 in parameter for consistency (and status file)
00251         replacementParam.second.push_back(std::string("2"));
00252       }
00253     else
00254       {
00255         t = atof(replacementParam.second[0].c_str());
00256         if (t>=2)
00257           {                        // build the appropriate deafult value
00258             tSize = unsigned(t);
00259           }
00260         else
00261           {
00262             throw std::runtime_error("Sorry, only deterministic tournament available at the moment");
00263           }
00264       }
00265     ptReplace = new eoMGGReplacement<EOT>(-surviveParents, tSize);    
00266     _state.storeFunctor(ptReplace);
00267     }
00268   else {   // until the end of what was the only loop/switch
00269     
00270   // the default deafult values
00271   eoHowMany elite (0.0);
00272   bool strongElitism (false);
00273   eoHowMany surviveParents (0.0);
00274   eoParamParamType reduceParentType ("Deterministic");
00275   eoHowMany surviveOffspring (1.0);
00276   eoParamParamType reduceOffspringType ("Deterministic");
00277   eoParamParamType reduceFinalType ("Deterministic");
00278 
00279   // depending on the value entered by the user, change some of the above
00280   double t;
00281 
00282   // ---------- General
00283   if (replacementParam.first == std::string("General"))
00284   {
00285     ;                              // defaults OK
00286   }
00287   // ---------- ESComma
00288   else if (replacementParam.first == std::string("ESComma"))
00289   {
00290     ;                              // OK too
00291   }
00292   // ---------- ESPlus
00293   else if (replacementParam.first == std::string("ESPlus"))
00294   {
00295     surviveParents = eoHowMany(1.0);
00296   }
00297   // ---------- Generational
00298   else if (replacementParam.first == std::string("Generational"))
00299   {
00300     ;                        // OK too (we should check nb of offspring)
00301   }
00302   // ---------- EP
00303   else if (replacementParam.first == std::string("EP"))
00304   {
00305     if (!replacementParam.second.size())   // no parameter added
00306       {
00307         std::cerr << "WARNING, no parameter passed to EP replacement, using 6" << std::endl;
00308         // put back 6 in parameter for consistency (and status file)
00309         replacementParam.second.push_back(std::string("6"));
00310       }
00311     // by coincidence, the syntax for the EP reducer is the same than here:
00312     reduceFinalType = replacementParam;
00313     surviveParents = eoHowMany(1.0);
00314   }
00315   // ---------- SSGA
00316   else if (replacementParam.first == std::string("SSGA"))
00317   {
00318     if (!replacementParam.second.size())   // no parameter added
00319       {
00320         std::cerr << "WARNING, no parameter passed to SSGA replacement, using 2" << std::endl;
00321         // put back 2 in parameter for consistency (and status file)
00322         replacementParam.second.push_back(std::string("2"));
00323         reduceParentType = eoParamParamType(std::string("DetTour(2)"));
00324       }
00325     else
00326       {
00327         t = atof(replacementParam.second[0].c_str());
00328         if (t>=2)
00329           {                        // build the appropriate deafult value
00330             reduceParentType = eoParamParamType(std::string("DetTour(") + replacementParam.second[0].c_str() + ")");
00331           }
00332         else   // check for [0.5,1] will be made in make_general_replacement
00333           {                        // build the appropriate deafult value
00334             reduceParentType = eoParamParamType(std::string("StochTour(") + replacementParam.second[0].c_str() + ")");
00335           }
00336       }
00337     // 
00338     surviveParents = eoHowMany(-1);
00339     surviveOffspring = eoHowMany(1);
00340   }
00341   else                 // no replacement recognized
00342     {
00343       throw std::runtime_error("Invalid replacement type " + replacementParam.first);
00344     }
00345 
00346   ptReplace = & make_general_replacement<EOT>(
00347      _parser, _state, elite, strongElitism, surviveParents, reduceParentType, surviveOffspring, reduceOffspringType, reduceFinalType);
00348 
00349   } // end of the ugly construct due to G3 and MGG - totaly heterogeneous at the moment
00350 
00351 
00353   // the general breeder
00355   eoGeneralBreeder<EOT> *breed = 
00356     new eoGeneralBreeder<EOT>(*select, _op, offspringRateParam.value());
00357   _state.storeFunctor(breed);
00358 
00360   // now the eoEasyEA
00362   eoAlgo<EOT> *algo = new eoEasyEA<EOT>(_continue, _eval, *breed, *ptReplace);
00363   _state.storeFunctor(algo);
00364   // that's it!
00365   return *algo;
00366 }
00367 
00368 #endif

Generated on Thu Oct 19 05:06:40 2006 for EO by  doxygen 1.3.9.1