EvolvingObjects
|
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