# 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
    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 }
    00310
    00311 #endif