From 7bf32a66fd13766b499859733fe362422ffb65af Mon Sep 17 00:00:00 2001 From: evomarc Date: Fri, 23 Aug 2002 15:52:40 +0000 Subject: [PATCH] Adding make_xxx files for EASEA --- eo/src/do/make_algo_easea.h | 368 +++++++++++++++++++++++++++ eo/src/do/make_general_replacement.h | 173 +++++++++++++ 2 files changed, 541 insertions(+) create mode 100644 eo/src/do/make_algo_easea.h create mode 100644 eo/src/do/make_general_replacement.h diff --git a/eo/src/do/make_algo_easea.h b/eo/src/do/make_algo_easea.h new file mode 100644 index 00000000..605264b9 --- /dev/null +++ b/eo/src/do/make_algo_easea.h @@ -0,0 +1,368 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_algo_easea.h +// (c) Marc Schoenauer and Pierre Collet, 2002 +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: Pierre.Collet@polytechnique.fr + Marc.Schoenauer@polytechnique.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _make_algo_easea_h +#define _make_algo_easea_h + +#include // for eo_is_a_rate +// everything tha's needed for the algorithms - SCALAR fitness + +// Selection +// the eoSelectOne's +#include +#include +#include +#include +#include +#include +#include +// #include included in all others + +// Breeders +#include + +// Replacement +#include "make_general_replacement.h" +#include "eoMGGReplacement.h" +#include "eoG3Replacement.h" + + +// Algorithm (only this one needed) +#include + + // also need the parser and param includes +#include +#include + + +/* + * This function builds the algorithm (i.e. selection and replacement) + * from existing continue (or checkpoint) and operators + * + * It uses a parser (to get user parameters) and a state (to store the memory) + * the last argument is an individual, needed for 2 reasons + * it disambiguates the call after instanciations + * some operator might need some private information about the indis + * + * This is why the template is the complete EOT even though only the fitness + * is actually templatized here +*/ + +template +eoAlgo & do_make_algo_scalar(eoParser& _parser, eoState& _state, eoEvalFunc& _eval, eoContinue& _continue, eoGenOp& _op) +{ + // the selection + eoValueParam& selectionParam = _parser.createParam(eoParamParamType("DetTour(2)"), "selection", "Selection: Roulette, Ranking(p,e), DetTour(T), StochTour(t), Sequential(ordered/unordered) or EliteSequentialSelect", 'S', "Evolution Engine"); + + eoParamParamType & ppSelect = selectionParam.value(); // pair > + + eoSelectOne* select ; + if (ppSelect.first == string("DetTour")) + { + unsigned detSize; + + if (!ppSelect.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to DetTour, using 2" << endl; + detSize = 2; + // put back 2 in parameter for consistency (and status file) + ppSelect.second.push_back(string("2")); + } + else // parameter passed by user as DetTour(T) + detSize = atoi(ppSelect.second[0].c_str()); + select = new eoDetTournamentSelect(detSize); + } + else if (ppSelect.first == string("StochTour")) + { + double p; + if (!ppSelect.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to StochTour, using 1" << endl; + p = 1; + // put back p in parameter for consistency (and status file) + ppSelect.second.push_back(string("1")); + } + else // parameter passed by user as DetTour(T) + p = atof(ppSelect.second[0].c_str()); + + select = new eoStochTournamentSelect(p); + } + else if (ppSelect.first == string("Ranking")) + { + double p,e; + if (ppSelect.second.size()==2) // 2 parameters: pressure and exponent + { + p = atof(ppSelect.second[0].c_str()); + e = atof(ppSelect.second[1].c_str()); + } + else if (ppSelect.second.size()==1) // 1 parameter: pressure + { + cerr << "WARNING, no exponent to Ranking, using 1" << endl; + e = 1; + ppSelect.second.push_back(string("1")); + p = atof(ppSelect.second[0].c_str()); + } + else // no parameters ... or garbage + { + cerr << "WARNING, no parameter to Ranking, using (2,1)" << endl; + p=2; + e=1; + // put back in parameter for consistency (and status file) + ppSelect.second.resize(2); // just in case + ppSelect.second[0] = (string("2")); + ppSelect.second[1] = (string("1")); + } + // check for authorized values + // pressure in (0,1] + if ( (p<=1) || (p>2) ) + { + cerr << "WARNING, selective pressure must be in (1,2] in Ranking, using 2\n"; + p=2; + ppSelect.second[0] = (string("2")); + } + // exponent >0 + if (e<=0) + { + cerr << "WARNING, exponent must be positive in Ranking, using 1\n"; + e=1; + ppSelect.second[1] = (string("1")); + } + // now we're OK + eoPerf2Worth & p2w = _state.storeFunctor( new eoRanking(p,e) ); + select = new eoRouletteWorthSelect(p2w); + } + else if (ppSelect.first == string("Sequential")) // one after the other + { + bool b; + if (ppSelect.second.size() == 0) // no argument -> default = ordered + { + b=true; + // put back in parameter for consistency (and status file) + ppSelect.second.push_back(string("ordered")); + } + else + b = !(ppSelect.second[0] == string("unordered")); + select = new eoSequentialSelect(b); + } + else if (ppSelect.first == string("EliteSequential")) // Best first, one after the other in random order afterwards + { + select = new eoEliteSequentialSelect; + } + else if (ppSelect.first == string("Roulette")) // no argument (yet) + { + select = new eoProportionalSelect; + } + else if (ppSelect.first == string("Random")) // no argument + { + select = new eoRandomSelect; + } + else + { + string stmp = string("Invalid selection: ") + ppSelect.first; + throw runtime_error(stmp.c_str()); + } + + _state.storeFunctor(select); + + // the number of offspring + eoValueParam& offspringRateParam = _parser.createParam(eoHowMany(1.0), "nbOffspring", "Nb of offspring (percentage or absolute)", 'O', "Evolution Engine"); + + ///////////////////////////////////////////////////// + // the replacement + ///////////////////////////////////////////////////// + + /** Replacement type - high level: predefined replacements + * ESComma : + * elite = 0 + * surviveParents=0 (no reduce) + * surviveOffspring=100% (no reduce) + * reduceFinal = Deterministic + * + * ESPlus : idem, except for + * surviveParents = 100% + * + * GGA : generational GA - idem ESComma except for + * offspringRate = 100% + * all reducers are unused + * + * SSGA(T/t) : Steady-State GA + * surviveParents = 1.0 - offspringRate + * reduceFinal = DetTour(T>1) ou StochTour(0.5 * ptReplace; + + // first, separate G3 and MGG + // maybe one day we have a common class - but is it really necessary??? + if (replacementParam.first == string("G3")) + { + // reduce the parents: by default, survive parents = -2 === 2 parents die + eoHowMany surviveParents = _parser.createParam(eoHowMany(-2,false), "surviveParents", "Nb of surviving parents (percentage or absolute)", '\0', "Evolution Engine / Replacement").value(); + // at the moment, this is the only argument + ptReplace = new eoG3Replacement(-surviveParents); // must receive nb of eliminated parets! + _state.storeFunctor(ptReplace); + } + else if (replacementParam.first == string("MGG")) + { + float t; + unsigned tSize; + // reduce the parents: by default, survive parents = -2 === 2 parents die + eoHowMany surviveParents = _parser.createParam(eoHowMany(-2,false), "surviveParents", "Nb of surviving parents (percentage or absolute)", '\0', "Evolution Engine / Replacement").value(); + // the tournament size + if (!replacementParam.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to MGG replacement, using 2" << endl; + tSize = 2; + // put back 2 in parameter for consistency (and status file) + replacementParam.second.push_back(string("2")); + } + else + { + t = atof(replacementParam.second[0].c_str()); + if (t>=2) + { // build the appropriate deafult value + tSize = unsigned(t); + } + else + { + throw runtime_error("Sorry, only deterministic tournament available at the moment"); + } + } + ptReplace = new eoMGGReplacement(-surviveParents, tSize); + _state.storeFunctor(ptReplace); + } + else { // until the end of what was the only loop/switch + + // the default deafult values + eoHowMany elite (0.0); + bool strongElitism (false); + eoHowMany surviveParents (0.0); + eoParamParamType reduceParentType ("Deterministic"); + eoHowMany surviveOffspring (1.0); + eoParamParamType reduceOffspringType ("Deterministic"); + eoParamParamType reduceFinalType ("Deterministic"); + + // depending on the value entered by the user, change some of the above + double t; + + // ---------- General + if (replacementParam.first == string("General")) + { + ; // defaults OK + } + // ---------- ESComma + else if (replacementParam.first == string("ESComma")) + { + ; // OK too + } + // ---------- ESPlus + else if (replacementParam.first == string("ESPlus")) + { + surviveParents = eoHowMany(1.0); + } + // ---------- Generational + else if (replacementParam.first == string("Generational")) + { + ; // OK too (we should check nb of offspring) + } + // ---------- EP + else if (replacementParam.first == string("EP")) + { + if (!replacementParam.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to EP replacement, using 6" << endl; + // put back 6 in parameter for consistency (and status file) + replacementParam.second.push_back(string("6")); + } + // by coincidence, the syntax for the EP reducer is the same than here: + reduceFinalType = replacementParam; + surviveParents = eoHowMany(1.0); + } + // ---------- SSGA + else if (replacementParam.first == string("SSGA")) + { + if (!replacementParam.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to SSGA replacement, using 2" << endl; + // put back 2 in parameter for consistency (and status file) + replacementParam.second.push_back(string("2")); + reduceParentType = eoParamParamType(string("DetTour(2)")); + } + else + { + t = atof(replacementParam.second[0].c_str()); + if (t>=2) + { // build the appropriate deafult value + reduceParentType = eoParamParamType(string("DetTour(") + replacementParam.second[0].c_str() + ")"); + } + else // check for [0.5,1] will be made in make_general_replacement + { // build the appropriate deafult value + reduceParentType = eoParamParamType(string("StochTour(") + replacementParam.second[0].c_str() + ")"); + } + } + // + surviveParents = eoHowMany(-1); + surviveOffspring = eoHowMany(1); + } + else // no replacement recognized + { + throw runtime_error("Invalid replacement type " + replacementParam.first); + } + + ptReplace = & make_general_replacement( + _parser, _state, elite, strongElitism, surviveParents, reduceParentType, surviveOffspring, reduceOffspringType, reduceFinalType); + + } // end of the ugly construct due to G3 and MGG - totaly heterogeneous at the moment + + + /////////////////////////////// + // the general breeder + /////////////////////////////// + eoGeneralBreeder *breed = + new eoGeneralBreeder(*select, _op, offspringRateParam.value()); + _state.storeFunctor(breed); + + /////////////////////////////// + // now the eoEasyEA + /////////////////////////////// + eoAlgo *algo = new eoEasyEA(_continue, _eval, *breed, *ptReplace); + _state.storeFunctor(algo); + // that's it! + return *algo; +} + +#endif diff --git a/eo/src/do/make_general_replacement.h b/eo/src/do/make_general_replacement.h new file mode 100644 index 00000000..72358f4d --- /dev/null +++ b/eo/src/do/make_general_replacement.h @@ -0,0 +1,173 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_general_replacement.h +// (c) Marc Schoenauer and Pierre Collet, 2002 +/* + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + Marc.Schoenauer@polytechnique.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _make_general_replacement_h +#define _make_general_replacement_h + +#include // for eo_is_a_rate + +// Replacement +#include + +// also need the parser and param includes +#include +#include + + +/** a helper function that decodes a parameter read by the parser into an + * eoReduce & (allocates the pointer and stores it into an eoState) + */ +template +eoReduce & decode_reduce(eoParamParamType & _ppReduce, eoState & _state) +{ + unsigned int detSize; + eoReduce * ptReduce; + + // ---------- Deterministic + if (_ppReduce.first == string("Deterministic")) + { + ptReduce = new eoTruncate; + } + // ---------- EP + else if (_ppReduce.first == string("EP")) + { + if (!_ppReduce.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to EP, using 6" << endl; + detSize = 6; + // put back 6 in parameter for consistency (and status file) + _ppReduce.second.push_back(string("6")); + } + else // parameter passed by user as EP(T) + detSize = atoi(_ppReduce.second[0].c_str()); + ptReduce = new eoEPReduce(detSize); + } + // ---------- DetTour + else if (_ppReduce.first == string("DetTour")) + { + if (!_ppReduce.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to DetTour, using 2" << endl; + detSize = 2; + // put back 2 in parameter for consistency (and status file) + _ppReduce.second.push_back(string("2")); + } + else // parameter passed by user as DetTour(T) + detSize = atoi(_ppReduce.second[0].c_str()); + ptReduce = new eoDetTournamentTruncate(detSize); + } + else if (_ppReduce.first == string("StochTour")) + { + double p; + if (!_ppReduce.second.size()) // no parameter added + { + cerr << "WARNING, no parameter passed to StochTour, using 1" << endl; + p = 1; + // put back p in parameter for consistency (and status file) + _ppReduce.second.push_back(string("1")); + } + else // parameter passed by user as DetTour(T) + { + p = atof(_ppReduce.second[0].c_str()); + if ( (p<=0.5) || (p>1) ) + throw runtime_error("Stochastic tournament size should be in [0.5,1]"); + } + + ptReduce = new eoStochTournamentTruncate(p); + } + else if (_ppReduce.first == string("Uniform")) + { + ptReduce = new eoRandomReduce; + } + // all done, stores and return a reference + _state.storeFunctor(ptReduce); + return (*ptReduce); +} + +/** Helper function that creates a replacement from the class + * eoReduceMergeReduce using 6 parameters + * (after the usual eoState and eoParser) + * + * eoHowMany _elite the number of elite parents (0 = no elitism) + * see below + * bool _strongElitism if elite > 0, string elitism or weak elitism + * strong = elite parents survive, whatever the offspring + * weak - elite patents compete AFTER replacement with best offspring + * eoHowMany _surviveParents number of parents after parents recuction + * eoParamParamType & _reduceParentType how the parents are reduced + * eoHowMany _surviveOffspring number of offspring after offspring recuction + * eoParamParamType & _reduceOffspringType how the offspring are reduced + * eoParamParamType & _reduceFinalType how the final population is reduced to initial population size + */ + +template +eoReplacement & make_general_replacement( + eoParser& _parser, eoState& _state, + eoHowMany _elite = eoHowMany(0), + bool _strongElitism = false, + eoHowMany _surviveParents = eoHowMany(0.0), + eoParamParamType & _reduceParentType = eoParamParamType("Deterministic"), + eoHowMany _surviveOffspring = eoHowMany(1.0), + eoParamParamType & _reduceOffspringType = eoParamParamType("Deterministic"), + eoParamParamType & _reduceFinalType = eoParamParamType("Deterministic") + ) +{ + ///////////////////////////////////////////////////// + // the replacement + ///////////////////////////////////////////////////// + + // Elitism + eoHowMany elite = _parser.createParam(_elite, "elite", "Nb of elite parents (percentage or absolute)", '\0', "Evolution Engine / Replacement").value(); + + bool strongElitism = _parser.createParam(_strongElitism,"eliteType", "Strong (true) or weak (false) elitism (set elite to 0 for none)", '\0', "Evolution Engine / Replacement").value(); + + // reduce the parents + eoHowMany surviveParents = _parser.createParam(_surviveParents, "surviveParents", "Nb of surviving parents (percentage or absolute)", '\0', "Evolution Engine / Replacement").value(); + + eoParamParamType & reduceParentType = _parser.createParam(_reduceParentType, "reduceParents", "Parents reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform", '\0', "Evolution Engine / Replacement").value(); + + eoReduce & reduceParent = decode_reduce(reduceParentType, _state); + + // reduce the offspring + eoHowMany surviveOffspring = _parser.createParam(_surviveOffspring, "surviveOffspring", "Nb of surviving offspring (percentage or absolute)", '\0', "Evolution Engine / Replacement").value(); + + eoParamParamType & reduceOffspringType = _parser.createParam(_reduceOffspringType, "reduceOffspring", "Offspring reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform", '\0', "Evolution Engine / Replacement").value(); + + eoReduce & reduceOffspring = decode_reduce(reduceOffspringType, _state); + + eoParamParamType & reduceFinalType = _parser.createParam(_reduceFinalType, "reduceFinal", "Final reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform", '\0', "Evolution Engine / Replacement").value(); + + eoReduce & reduceFinal = decode_reduce(reduceFinalType, _state); + + // now the replacement itself + eoReduceMergeReduce *ptReplace = new eoReduceMergeReduce(elite, strongElitism, surviveParents, reduceParent, surviveOffspring, reduceOffspring, reduceFinal); + _state.storeFunctor(ptReplace); + + // that's it! + return *ptReplace; +} + +#endif