From 0816b742d9ae3937f8cb27dfae74e9d3fccfae6f Mon Sep 17 00:00:00 2001 From: evomarc Date: Thu, 8 Nov 2001 06:49:38 +0000 Subject: [PATCH] Adding PBIL files - simple PBIL algorithm with simple additive update rule --- eo/src/ga/eoPBILAdditive.h | 120 +++++++++++++++++++++++++++++++++++ eo/src/ga/eoPBILDistrib.h | 103 ++++++++++++++++++++++++++++++ eo/src/ga/eoPBILOrg.h | 78 +++++++++++++++++++++++ eo/src/ga/make_PBILdistrib.h | 89 ++++++++++++++++++++++++++ eo/src/ga/make_PBILupdate.h | 80 +++++++++++++++++++++++ 5 files changed, 470 insertions(+) create mode 100644 eo/src/ga/eoPBILAdditive.h create mode 100644 eo/src/ga/eoPBILDistrib.h create mode 100644 eo/src/ga/eoPBILOrg.h create mode 100644 eo/src/ga/make_PBILdistrib.h create mode 100644 eo/src/ga/make_PBILupdate.h diff --git a/eo/src/ga/eoPBILAdditive.h b/eo/src/ga/eoPBILAdditive.h new file mode 100644 index 00000000..577c2328 --- /dev/null +++ b/eo/src/ga/eoPBILAdditive.h @@ -0,0 +1,120 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoPBILDistrib.h +// (c) Marc Schoenauer, Maarten Keijzer, 2001 +/* + 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: Marc.Schoenauer@polytechnique.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoPBILAdditive_H +#define _eoPBILAdditive_H + +#include +#include + +/** + * Distribution Class for PBIL algorithm + * (Population-Based Incremental Learning, Baluja and Caruana 96) + * + * This class implements an extended update rule: + * in the original paper, the authors used + * + * p(i)(t+1) = (1-LR)*p(i)(t) + LR*best(i) + * + * here the same formula is applied, with some of the best individuals + * and for some of the worst individuals (with different learning rates) +*/ + +template +class eoPBILAdditive : public eoDistribUpdater +{ +public: + /** Ctor with parameters + * using the default values is equivalent to using eoPBILOrg + */ + eoPBILAdditive(double _LRBest, unsigned _nbBest = 1, + double _tolerance=0.0, + double _LRWorst = 0.0, unsigned _nbWorst = 0 ) : + maxBound(1.0-_tolerance), minBound(_tolerance), + LR(0.0), nbBest(_nbBest), nbWorst(_nbWorst) + { + if (nbBest+nbWorst == 0) + throw runtime_error("Must update either from best or from worst in eoPBILAdditive"); + + if (_nbBest) + { + lrb = _LRBest/_nbBest; + LR += _LRBest; + } + else + lrb=0.0; // just in case + if (_nbWorst) + { + lrw = _LRWorst/_nbWorst; + LR += _LRWorst; + } + else + lrw=0.0; // just in case + } + + /** Update the distribution from the current population */ + virtual void operator()(eoDistribution & _distrib, eoPop& _pop) + { + eoPBILDistrib& distrib = dynamic_cast&>(_distrib); + + vector & p = distrib.value(); + + unsigned i, popSize=_pop.size(); + vector result; + _pop.sort(result); // is it necessary to sort the whole population? + // but I'm soooooooo lazy !!! + + for (unsigned g=0; g=popSize-nbWorst; i--) + { + const EOT & best = (*result[i]); + if ( !best[g] ) // if 0, increase proba + p[g] += lrw; + } + // stay in [0,1] (possibly strictly due to tolerance) + p[g] = min(maxBound, p[g]); + p[g] = max(minBound, p[g]); + } + } + +private: + double maxBound, minBound; // proba stay away from 0 and 1 by at least tolerance + double LR; // learning rate + unsigned nbBest; // number of Best individuals used for update + unsigned nbWorst; // number of Worse individuals used for update + double lrb, lrw; // "local" learning rates (see operator()) +}; + +#endif diff --git a/eo/src/ga/eoPBILDistrib.h b/eo/src/ga/eoPBILDistrib.h new file mode 100644 index 00000000..9d0558d0 --- /dev/null +++ b/eo/src/ga/eoPBILDistrib.h @@ -0,0 +1,103 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoPBILDistrib.h +// (c) Marc Schoenauer, 2001 +/* + 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: Marc.Schoenauer@inria.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _eoPBILDistrib_H +#define _eoPBILDistrib_H + +#include + +/** + * Distribution Class for PBIL algorithm + * (Population-Based Incremental Learning, Baluja and Caruana 96) + * + * It encodes a univariate distribution on the space of bitstrings, + * i.e. one probability for each bit to be one + * + * It is an eoValueParam > : + * the vector stores the probabilities that each bit is 1 + * + * It is still pure virtual, as the update method needs to be specified +*/ + +template +class eoPBILDistrib : public eoDistribution, + public eoValueParam > +{ +public: + /** Ctor with size of genomes, and update parameters */ + eoPBILDistrib(unsigned _genomeSize) : + eoDistribution(), + eoValueParam >(vector(_genomeSize, 0.5), "Distribution"), + genomeSize(_genomeSize) + {} + + /** the randomizer of indis */ + virtual void operator()(EOT & _eo) + { + _eo.resize(genomeSize); // just in case + for (unsigned i=0; i&) = 0; // update from a population + + /** Accessor to the genome size */ + unsigned Size() {return genomeSize;} + + /** printing... */ + virtual void printOn(ostream& os) const + { + os << value().size() << ' '; + for (unsigned i=0; i> sz; + + value().resize(sz); + unsigned i; + + for (i = 0; i < sz; ++i) + { + double atom; + is >> atom; + value()[i] = atom; + } + } + + unsigned int size() {return genomeSize;} + + virtual string className() const {return "eoPBILDistrib";}; + +private: + unsigned genomeSize; // size of indis +}; + +#endif diff --git a/eo/src/ga/eoPBILOrg.h b/eo/src/ga/eoPBILOrg.h new file mode 100644 index 00000000..d4cf8c05 --- /dev/null +++ b/eo/src/ga/eoPBILOrg.h @@ -0,0 +1,78 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoPBILDistrib.h +// (c) Marc Schoenauer, Maarten Keijzer, 2001 +/* + 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: Marc.Schoenauer@polytechnique.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _eoPBILOrg_H +#define _eoPBILOrg_H + +#include +#include + +/** + * Distribution Class for PBIL algorithm + * (Population-Based Incremental Learning, Baluja and Caruana 96) + * + * This class implements the update rule from the original paper: + * + * p(i)(t+1) = (1-LR)*p(i)(t) + LR*best(i) +*/ + +template +class eoPBILOrg : public eoDistribUpdater +{ +public: + /** Ctor with size of genomes, and update parameters */ + eoPBILOrg(double _LR, double _tolerance=0.0 ) : + LR(_LR), maxBound(1.0-_tolerance), minBound(_tolerance) + {} + + + /** Update the distribution from the current population */ + virtual void operator()(eoDistribution & _distrib, eoPop& _pop) + { + const EOT & best = _pop.best_element(); + eoPBILDistrib& distrib = dynamic_cast&>(_distrib); + + vector & p = distrib.value(); + + for (unsigned g=0; g // for time(0) for random seeding +#include +#include +#include +#include + + +//////////////////////////DISTRIB CONSTRUCTION /////////////////////////////// +/** + * Templatized version of parser-based construct of the distribution + * for PBIL distribution evolution algorithm + * + * It must then be instantiated, and compiled on its own for a given EOType + * (see test/t-eoPBIL.cpp + * + * Last argument is template-disambiguating +*/ + + +template +eoPBILDistrib & do_make_PBILdistrib(eoParser & _parser, eoState& _state, EOT) +{ + // First the random seed + eoValueParam& seedParam = _parser.createParam(uint32(0), "seed", "Random number seed", 'S'); + if (seedParam.value() == 0) + seedParam.value() = time(0); + + // the representation dependent stuff + unsigned chromSize = _parser.createParam(unsigned(10), "chromSize", "The length of the bitstrings", 'n',"Algorithm").value(); + + eoPBILDistrib * ptDistrib = new eoPBILDistrib(chromSize); + _state.storeFunctor(ptDistrib); + + // now the initialization: read a previously saved distribution, or random + eoValueParam& loadNameParam = _parser.createParam(string(""), "Load","A save file to restart from",'L', "Persistence" ); + if (loadNameParam.value() != "") // something to load + { + // create another state for reading + eoState inState; // a state for loading - WITHOUT the parser + // register the rng and the distribution in the state, + // so they can be loaded, + // and the present run will be the exact continuation of the saved run + // eventually with different parameters + inState.registerObject(*ptDistrib); + inState.registerObject(rng); + inState.load(loadNameParam.value()); // load the distrib and the rng + } + else // nothing loaded from a file + { + rng.reseed(seedParam.value()); + } + + // for future stateSave, register the algorithm into the state + _state.registerObject(_parser); + _state.registerObject(*ptDistrib); + _state.registerObject(rng); + + return *ptDistrib; +} + +#endif diff --git a/eo/src/ga/make_PBILupdate.h b/eo/src/ga/make_PBILupdate.h new file mode 100644 index 00000000..7cf371b4 --- /dev/null +++ b/eo/src/ga/make_PBILupdate.h @@ -0,0 +1,80 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// make_PBILupdate.h +// (c) Marc Schoenauer, Maarten Keijzer, 2001 +/* + 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: Marc.Schoenauer@polytechnique.fr + mkeijzer@dhi.dk + */ +//----------------------------------------------------------------------------- + +#ifndef _make_PBILupdate_h +#define _make_PBILupdate_h + +#include // for time(0) for random seeding +#include +#include +#include +#include + + +///////CONSTRUCTION of PBIL distribution updaters///////////////// +/** + * Templatized version of parser-based construct of the update rule for PBIL + * distributions (see eoPBILDistrib.h) + * + * It must then be instantiated, and compiled on its own for a given EOType + * (see test/t-eoPBIL.cpp) + * + * Last argument is template-disambiguating +*/ + + +template +eoDistribUpdater & do_make_PBILupdate(eoParser & _parser, eoState& _state, EOT) +{ + // ast the moment, a single update rule is available + // but at some point we'll have to choose among different rules + + string UType = _parser.createParam(string("PBIL"), "updateRule", "Type of update rule (only PBIL additive at the moment)", 'U', "Algorithm").value(); + + unsigned nbBest = _parser.createParam(unsigned(1), "nbBest", "Number of good guys to update from", 'B', "Algorithm").value(); + double LRBest = _parser.createParam(0.1, "LRBest", "Learning Rate (from best guys)", 'L', "Algorithm").value(); + unsigned nbWorst = _parser.createParam(unsigned(0), "nbWorst", "Number of bad guys to update from", 'W', "Algorithm").value(); + double LRWorst = _parser.createParam(0.01, "LRWorst", "Learning Rate (from best guys)", 'L', "Algorithm").value(); + double tolerance = _parser.createParam(0.0, "tolerance", "Keeping away from 0 and 1", 't', "Algorithm").value(); + + // a pointer to choose among several possible types + eoDistribUpdater * ptUpdate; + + if (UType == string("PBIL")) + { + if ( (nbWorst == 0) && (nbBest == 1) ) + ptUpdate = new eoPBILOrg(LRBest, tolerance); + else + ptUpdate = new eoPBILAdditive(LRBest, nbBest, tolerance, LRWorst, nbWorst); + } + else + throw runtime_error("Only PBIL additive update rule available at the moment"); + + // done: don't forget to store the allocated pointers + _state.storeFunctor(ptUpdate); + return *ptUpdate; +} + +#endif