EvolvingObjects
make_algo_scalar.h
00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
00002 
00003 //-----------------------------------------------------------------------------
00004 // make_algo_scalar.h
00005 // (c) Maarten Keijzer, Marc Schoenauer and GeNeura Team, 2001
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@polytechnique.fr
00023              mkeijzer@dhi.dk
00024  */
00025 //-----------------------------------------------------------------------------
00026 
00027 #ifndef _make_algo_scalar_h
00028 #define _make_algo_scalar_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 <eoSharingSelect.h>
00043 #include <utils/eoDistance.h>
00044 
00045 // Breeders
00046 #include <eoGeneralBreeder.h>
00047 
00048 // Replacement
00049 // #include <eoReplacement.h>
00050 #include <eoMergeReduce.h>
00051 #include <eoReduceMerge.h>
00052 #include <eoSurviveAndDie.h>
00053 
00054 // distance
00055 #include <utils/eoDistance.h>
00056 
00057 // Algorithm (only this one needed)
00058 #include <eoEasyEA.h>
00059 
00060   // also need the parser and param includes
00061 #include <utils/eoParser.h>
00062 #include <utils/eoState.h>
00063 
00064 
00065 /*
00066  * This function builds the algorithm (i.e. selection and replacement)
00067  *      from existing continue (or checkpoint) and operators
00068  *
00069  * It uses a parser (to get user parameters) and a state (to store the memory)
00070  * the last argument is an individual, needed for 2 reasons
00071  *     it disambiguates the call after instanciations
00072  *     some operator might need some private information about the indis
00073  *
00074  * This is why the template is the complete EOT even though only the fitness
00075  * is actually templatized here
00076  *
00077  * @ingroup Builders
00078 */
00079 template <class EOT>
00080 eoAlgo<EOT> & do_make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc<EOT>& _eval, eoContinue<EOT>& _continue, eoGenOp<EOT>& _op, eoDistance<EOT> * _dist = NULL)
00081 {
00082   // the selection : help and comment depend on whether or not a distance is passed
00083   std::string comment;
00084   if (_dist == NULL)
00085     comment = "Selection: DetTour(T), StochTour(t), Roulette, Ranking(p,e) or Sequential(ordered/unordered)";
00086       else
00087         comment = "Selection: DetTour(T), StochTour(t), Roulette, Ranking(p,e), Sharing(sigma_share) or Sequential(ordered/unordered)";
00088 
00089   eoValueParam<eoParamParamType>& selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection", comment, 'S', "Evolution Engine");
00090 
00091   eoParamParamType & ppSelect = selectionParam.value(); // std::pair<std::string,std::vector<std::string> >
00092 
00093   eoSelectOne<EOT>* select ;
00094   if (ppSelect.first == std::string("DetTour"))
00095   {
00096     unsigned detSize;
00097 
00098     if (!ppSelect.second.size())   // no parameter added
00099       {
00100         std::cerr << "WARNING, no parameter passed to DetTour, using 2" << std::endl;
00101         detSize = 2;
00102         // put back 2 in parameter for consistency (and status file)
00103         ppSelect.second.push_back(std::string("2"));
00104       }
00105     else          // parameter passed by user as DetTour(T)
00106       detSize = atoi(ppSelect.second[0].c_str());
00107     select = new eoDetTournamentSelect<EOT>(detSize);
00108   }
00109   else if (ppSelect.first == std::string("Sharing"))
00110   {
00111     double nicheSize;
00112 
00113     if (!ppSelect.second.size())   // no parameter added
00114       {
00115         std::cerr << "WARNING, no parameter passed to Sharing, using 0.5" << std::endl;
00116         nicheSize = 0.5;
00117         // put back 2 in parameter for consistency (and status file)
00118         ppSelect.second.push_back(std::string("0.5"));
00119       }
00120     else          // parameter passed by user as DetTour(T)
00121       nicheSize = atof(ppSelect.second[0].c_str());
00122     if (_dist == NULL)             // no distance
00123           throw std::runtime_error("You didn't specify a distance when calling make_algo_scalar and using sharing");
00124     select = new eoSharingSelect<EOT>(nicheSize, *_dist);
00125   }
00126   else if (ppSelect.first == std::string("StochTour"))
00127     {
00128       double p;
00129       if (!ppSelect.second.size())   // no parameter added
00130         {
00131           std::cerr << "WARNING, no parameter passed to StochTour, using 1" << std::endl;
00132           p = 1;
00133           // put back p in parameter for consistency (and status file)
00134           ppSelect.second.push_back(std::string("1"));
00135         }
00136       else        // parameter passed by user as DetTour(T)
00137         p = atof(ppSelect.second[0].c_str());
00138 
00139       select = new eoStochTournamentSelect<EOT>(p);
00140     }
00141   else if (ppSelect.first == std::string("Ranking"))
00142     {
00143       double p,e;
00144       if (ppSelect.second.size()==2)   // 2 parameters: pressure and exponent
00145         {
00146           p = atof(ppSelect.second[0].c_str());
00147           e = atof(ppSelect.second[1].c_str());
00148         }
00149       else if (ppSelect.second.size()==1)   // 1 parameter: pressure
00150         {
00151           std::cerr << "WARNING, no exponent to Ranking, using 1" << std::endl;
00152           e = 1;
00153           ppSelect.second.push_back(std::string("1"));
00154           p = atof(ppSelect.second[0].c_str());
00155         }
00156       else // no parameters ... or garbage
00157         {
00158           std::cerr << "WARNING, no parameter to Ranking, using (2,1)" << std::endl;
00159           p=2;
00160           e=1;
00161           // put back in parameter for consistency (and status file)
00162           ppSelect.second.resize(2); // just in case
00163           ppSelect.second[0] = (std::string("2"));
00164           ppSelect.second[1] = (std::string("1"));
00165         }
00166       // check for authorized values
00167       // pressure in (0,1]
00168       if ( (p<=1) || (p>2) )
00169         {
00170           std::cerr << "WARNING, selective pressure must be in (0,1] in Ranking, using 2\n";
00171           p=2;
00172           ppSelect.second[0] = (std::string("2"));
00173         }
00174       // exponent >0
00175       if (e<=0)
00176         {
00177           std::cerr << "WARNING, exponent must be positive in Ranking, using 1\n";
00178           e=1;
00179           ppSelect.second[1] = (std::string("1"));
00180         }
00181       // now we're OK
00182       eoPerf2Worth<EOT> & p2w = _state.storeFunctor( new eoRanking<EOT>(p,e) );
00183       select = new eoRouletteWorthSelect<EOT>(p2w);
00184     }
00185   else if (ppSelect.first == std::string("Sequential")) // one after the other
00186     {
00187       bool b;
00188       if (ppSelect.second.size() == 0)   // no argument -> default = ordered
00189         {
00190           b=true;
00191           // put back in parameter for consistency (and status file)
00192           ppSelect.second.push_back(std::string("ordered"));
00193         }
00194       else
00195         b = !(ppSelect.second[0] == std::string("unordered"));
00196       select = new eoSequentialSelect<EOT>(b);
00197     }
00198   else if (ppSelect.first == std::string("Roulette")) // no argument (yet)
00199     {
00200       select = new eoProportionalSelect<EOT>;
00201     }
00202   else if (ppSelect.first == std::string("Random")) // no argument
00203     {
00204       select = new eoRandomSelect<EOT>;
00205     }
00206   else
00207     {
00208       std::string stmp = std::string("Invalid selection: ") + ppSelect.first;
00209       throw std::runtime_error(stmp.c_str());
00210     }
00211 
00212   _state.storeFunctor(select);
00213 
00214   // the number of offspring
00215     eoValueParam<eoHowMany>& offspringRateParam =  _parser.createParam(eoHowMany(1.0), "nbOffspring", "Nb of offspring (percentage or absolute)", 'O', "Evolution Engine");
00216 
00217   // the replacement
00218   eoValueParam<eoParamParamType>& replacementParam = _parser.createParam(eoParamParamType("Comma"), "replacement", "Replacement: Comma, Plus or EPTour(T), SSGAWorst, SSGADet(T), SSGAStoch(t)", 'R', "Evolution Engine");
00219 
00220   eoParamParamType & ppReplace = replacementParam.value(); // std::pair<std::string,std::vector<std::string> >
00221 
00222   eoReplacement<EOT>* replace ;
00223   if (ppReplace.first == std::string("Comma")) // Comma == generational
00224   {
00225     replace = new eoCommaReplacement<EOT>;
00226   }
00227   else if (ppReplace.first == std::string("Plus"))
00228     {
00229       replace = new eoPlusReplacement<EOT>;
00230     }
00231   else if (ppReplace.first == std::string("EPTour"))
00232     {
00233       unsigned detSize;
00234 
00235       if (!ppReplace.second.size())   // no parameter added
00236         {
00237           std::cerr << "WARNING, no parameter passed to EPTour, using 6" << std::endl;
00238           detSize = 6;
00239           // put back in parameter for consistency (and status file)
00240           ppReplace.second.push_back(std::string("6"));
00241         }
00242       else        // parameter passed by user as EPTour(T)
00243         detSize = atoi(ppSelect.second[0].c_str());
00244 
00245       replace = new eoEPReplacement<EOT>(detSize);
00246     }
00247   else if (ppReplace.first == std::string("SSGAWorst"))
00248     {
00249       replace = new eoSSGAWorseReplacement<EOT>;
00250     }
00251   else if (ppReplace.first == std::string("SSGADet"))
00252     {
00253       unsigned detSize;
00254 
00255       if (!ppReplace.second.size())   // no parameter added
00256         {
00257           std::cerr << "WARNING, no parameter passed to SSGADet, using 2" << std::endl;
00258           detSize = 2;
00259           // put back in parameter for consistency (and status file)
00260           ppReplace.second.push_back(std::string("2"));
00261         }
00262       else        // parameter passed by user as SSGADet(T)
00263         detSize = atoi(ppSelect.second[0].c_str());
00264 
00265       replace = new eoSSGADetTournamentReplacement<EOT>(detSize);
00266     }
00267   else if (ppReplace.first == std::string("SSGAStoch"))
00268     {
00269       double p;
00270       if (!ppReplace.second.size())   // no parameter added
00271         {
00272           std::cerr << "WARNING, no parameter passed to SSGAStoch, using 1" << std::endl;
00273           p = 1;
00274           // put back in parameter for consistency (and status file)
00275           ppReplace.second.push_back(std::string("1"));
00276         }
00277       else        // parameter passed by user as SSGADet(T)
00278         p = atof(ppSelect.second[0].c_str());
00279 
00280       replace = new eoSSGAStochTournamentReplacement<EOT>(p);
00281     }
00282   else
00283     {
00284       std::string stmp = std::string("Invalid replacement: ") + ppReplace.first;
00285       throw std::runtime_error(stmp.c_str());
00286     }
00287 
00288   _state.storeFunctor(replace);
00289 
00290   // adding weak elitism
00291   eoValueParam<bool>& weakElitismParam =  _parser.createParam(false, "weakElitism", "Old best parent replaces new worst offspring *if necessary*", 'w', "Evolution Engine");
00292   if (weakElitismParam.value())
00293     {
00294       eoReplacement<EOT> *replaceTmp = replace;
00295       replace = new eoWeakElitistReplacement<EOT>(*replaceTmp);
00296       _state.storeFunctor(replace);
00297     }
00298 
00299   // the general breeder
00300   eoGeneralBreeder<EOT> *breed =
00301     new eoGeneralBreeder<EOT>(*select, _op, offspringRateParam.value());
00302   _state.storeFunctor(breed);
00303 
00304   // now the eoEasyEA
00305   eoAlgo<EOT> *algo = new eoEasyEA<EOT>(_continue, _eval, *breed, *replace);
00306   _state.storeFunctor(algo);
00307   // that's it!
00308   return *algo;
00309 }
00313 #endif
 All Classes Namespaces Files Functions Variables Typedefs Friends