From bec7d02c50e06800b6ae77fc8280209f75702079 Mon Sep 17 00:00:00 2001 From: tlegrand Date: Mon, 2 Jul 2007 12:58:13 +0000 Subject: [PATCH] particle-swarm-optimization main templates added --- eo/src/PO.h | 203 ++++++++++++++++++ eo/src/eoBinaryFlight.h | 42 ++++ eo/src/eoBitParticle.h | 48 +++++ eo/src/eoConstrictedVariableWeightVelocity.h | 208 +++++++++++++++++++ eo/src/eoConstrictedVelocity.h | 191 +++++++++++++++++ eo/src/eoDummyFlight.h | 51 +++++ eo/src/eoEasyPSO.h | 129 ++++++++++++ eo/src/eoFixedInertiaWeightedVelocity.h | 190 +++++++++++++++++ eo/src/eoFlight.h | 54 +++++ eo/src/eoGaussRealWeightUp.h | 68 ++++++ eo/src/eoLSPSO.h | 184 ++++++++++++++++ eo/src/eoLinearDecreasingWeightUp.h | 75 +++++++ eo/src/eoLinearTopology.h | 199 ++++++++++++++++++ eo/src/eoNeighborhood.h | 66 ++++++ eo/src/eoPSO.h | 40 ++++ eo/src/eoParticleBestInit.h | 77 +++++++ eo/src/eoRandomRealWeightUp.h | 76 +++++++ eo/src/eoRealBoundModifier.h | 97 +++++++++ eo/src/eoRealParticle.h | 47 +++++ eo/src/eoSSPSO.h | 168 +++++++++++++++ eo/src/eoSigBinaryFlight.h | 86 ++++++++ eo/src/eoSocialNeighborhood.h | 134 ++++++++++++ eo/src/eoStandardFlight.h | 107 ++++++++++ eo/src/eoStandardVelocity.h | 175 ++++++++++++++++ eo/src/eoStarTopology.h | 136 ++++++++++++ eo/src/eoSyncEasyPSO.h | 138 ++++++++++++ eo/src/eoTimeContinue.h | 82 ++++++++ eo/src/eoTopology.h | 83 ++++++++ eo/src/eoVariableInertiaWeightedVelocity.h | 196 +++++++++++++++++ eo/src/eoVectorParticle.h | 130 ++++++++++++ eo/src/eoVelocity.h | 75 +++++++ eo/src/eoVelocityInit.h | 140 +++++++++++++ eo/src/eoWeightUpdater.h | 38 ++++ 33 files changed, 3733 insertions(+) create mode 100644 eo/src/PO.h create mode 100644 eo/src/eoBinaryFlight.h create mode 100644 eo/src/eoBitParticle.h create mode 100644 eo/src/eoConstrictedVariableWeightVelocity.h create mode 100644 eo/src/eoConstrictedVelocity.h create mode 100644 eo/src/eoDummyFlight.h create mode 100644 eo/src/eoEasyPSO.h create mode 100644 eo/src/eoFixedInertiaWeightedVelocity.h create mode 100644 eo/src/eoFlight.h create mode 100644 eo/src/eoGaussRealWeightUp.h create mode 100644 eo/src/eoLSPSO.h create mode 100644 eo/src/eoLinearDecreasingWeightUp.h create mode 100644 eo/src/eoLinearTopology.h create mode 100644 eo/src/eoNeighborhood.h create mode 100644 eo/src/eoPSO.h create mode 100644 eo/src/eoParticleBestInit.h create mode 100644 eo/src/eoRandomRealWeightUp.h create mode 100644 eo/src/eoRealBoundModifier.h create mode 100644 eo/src/eoRealParticle.h create mode 100644 eo/src/eoSSPSO.h create mode 100644 eo/src/eoSigBinaryFlight.h create mode 100644 eo/src/eoSocialNeighborhood.h create mode 100644 eo/src/eoStandardFlight.h create mode 100644 eo/src/eoStandardVelocity.h create mode 100644 eo/src/eoStarTopology.h create mode 100644 eo/src/eoSyncEasyPSO.h create mode 100644 eo/src/eoTimeContinue.h create mode 100644 eo/src/eoTopology.h create mode 100644 eo/src/eoVariableInertiaWeightedVelocity.h create mode 100644 eo/src/eoVectorParticle.h create mode 100644 eo/src/eoVelocity.h create mode 100644 eo/src/eoVelocityInit.h create mode 100644 eo/src/eoWeightUpdater.h diff --git a/eo/src/PO.h b/eo/src/PO.h new file mode 100644 index 00000000..530f2948 --- /dev/null +++ b/eo/src/PO.h @@ -0,0 +1,203 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// PO.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef PO_H +#define PO_H + +//----------------------------------------------------------------------------- +#include +#include +//----------------------------------------------------------------------------- + +/** PO inheriting from EO is specially designed for PSO particle.POs have got a fitness, + which at the same time needs to be only an object with the operation less than (<) + defined. A best fitness also belongs to the particle.Fitness says how + good is the particle for a current iteration whereas the best fitness can be saved for + many iterations. +*/ +template < class F > class PO:public EO < F > +{ + +public: + + typedef typename PO < F >::Fitness Fitness; + + /** Default constructor. + Fitness must have a ctor which takes 0 as a value. Best fitness mush also have the same constructor. + */ + PO ():repFitness (Fitness ()), invalidFitness (true), + bestFitness (Fitness()){} + + + /// Return fitness value. + Fitness fitness () const + { + if (invalid ()) + throw std::runtime_error ("invalid fitness in PO.h"); + return repFitness; + } + + + /** Set fitness. At the same time, validates it. + * @param _fitness New fitness value. + */ + void fitness (const Fitness & _fitness) + { + repFitness = _fitness; + invalidFitness = false; + } + + /** Return the best fitness. + * @return bestFitness + */ + Fitness best () const + { + if (invalid ()) + throw std::runtime_error ("invalid best fitness in PO.h"); + return bestFitness; + } + + + /** Set the best fitness. + * @param _bestFitness New best fitness found for the particle. + */ + void best (const Fitness & _bestFitness) + { + bestFitness = _bestFitness; + invalidBestFitness = false; + } + + + /** Return true If fitness value is invalid, false otherwise. + * @return true If fitness is invalid. + */ + bool invalid () const + { + return invalidFitness; + } + + /** Invalidate the fitness. + * @return + */ + void invalidate () + { + invalidFitness = true; + } + + /** Return true If the best fitness value is invalid, false otherwise. + * @return true If the bestfitness is invalid. + */ + bool invalidBest () const + { + return invalidBestFitness; + } + + /** Invalidate the best fitness. + * @return + */ + void invalidateBest () + { + invalidBestFitness = true; + } + + /** Return the class id. + * @return the class name as a std::string + */ + virtual std::string className () const + { + return "PO"; + } + + /** Returns true if + @return true if the fitness is higher + */ + bool operator< (const PO & _po2) const { return fitness () < _po2.fitness ();} + bool operator> (const PO & _po2) const { return !(fitness () <= _po2.fitness ());} + + /** + * Write object. Called printOn since it prints the object _on_ a stream. + * @param _os A std::ostream. + */ + virtual void printOn(std::ostream& _os) const { + + + // the latest version of the code. Very similar to the old code + if (invalid()) { + _os << "INVALID "; + } + else + { + _os << repFitness << ' ' ; + } + + if (invalidBest()) { + _os << "INVALID BEST"; + } + else + { + _os << "best: " << bestFitness ; + } + + } + + /** + * Read object.\\ + * Calls base class, just in case that one had something to do. + * The read and print methods should be compatible and have the same format. + * In principle, format is "plain": they just print a number + * @param _is a std::istream. + * @throw runtime_std::exception If a valid object can't be read. + */ + virtual void readFrom(std::istream& _is) { + + // the new version of the reafFrom function. + // It can distinguish between valid and invalid fitness values. + std::string fitness_str; + int pos = _is.tellg(); + _is >> fitness_str; + + if (fitness_str == "INVALID") + { + invalidFitness = true; + } + else + { + invalidFitness = false; + _is.seekg(pos); // rewind + _is >> repFitness; + } + } + +private: + Fitness repFitness; // value of fitness for this particle + bool invalidFitness; // true if the value of the fitness is invalid + + Fitness bestFitness; // value of the best fitness found for the particle + bool invalidBestFitness; // true if the value of the best fitness is invalid + +}; + +//----------------------------------------------------------------------------- + +#endif /*PO_H */ diff --git a/eo/src/eoBinaryFlight.h b/eo/src/eoBinaryFlight.h new file mode 100644 index 00000000..6c95d4d3 --- /dev/null +++ b/eo/src/eoBinaryFlight.h @@ -0,0 +1,42 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoBinaryFlight.h +// (c) OPAC Team, 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOBINARYFLIGHT_H +#define EOBINARYFLIGHT_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + + + +/** Abstract class for binary flight. Positions are updated but are expected to be binary. + * A function must be used to decide, according to continuous velocities, of the + * new positions (0,1 ... ?) + */ +template < class POT > class eoBinaryFlight:public eoFlight < POT >{}; + + + +#endif /*EOBINARYFLIGHT_H */ diff --git a/eo/src/eoBitParticle.h b/eo/src/eoBitParticle.h new file mode 100644 index 00000000..c319abe9 --- /dev/null +++ b/eo/src/eoBitParticle.h @@ -0,0 +1,48 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoBitParticle.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOBITPARTICLE_H +#define _EOBITPARTICLE_H + + +#include + + +/** eoBitParticle: Implementation of a bit-coded particle. + * Positions and best positions are 0 or 1 but the velocity is a vector of double. +*/ +template < class FitT> class eoBitParticle: public eoVectorParticle + +{ +public: + + eoBitParticle(unsigned size = 0, bool positions = 0,double velocities = 0.0,bool bestPositions = 0): eoVectorParticle (size, positions,velocities,bestPositions) {} + + virtual std::string className() const + { + return "eoBitParticle"; + } +}; + +#endif /*_EOBITPARTICLE_H*/ diff --git a/eo/src/eoConstrictedVariableWeightVelocity.h b/eo/src/eoConstrictedVariableWeightVelocity.h new file mode 100644 index 00000000..24c7c3b6 --- /dev/null +++ b/eo/src/eoConstrictedVariableWeightVelocity.h @@ -0,0 +1,208 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoConstrictedVariableWeightVelocity.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOCONSTRICTEDVARIABLEWEIGHTVELOCITY_H +#define EOCONSTRICTEDVARIABLEWEIGHTVELOCITY_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + + + +/** Inertia variable weighted based velocity performer + constriction. Derivated from abstract eoVelocity, +* At step t: v(t+1)= K * ( w*v(t) + c1*r1* (xbest(t)-x(t)) + c2*r2* (gbest(t) - x(t))) +* w is updated each time the velocity performer is called and K is fixed +* (ci given and Ri chosen at random in [0;1]). +*/ +template < class POT > class eoConstrictedVariableWeightVelocity:public eoVelocity < POT > +{ + +public: + + /* + * Each element for the velocity evaluation is expected to be of type VelocityType. + */ + typedef typename POT::ParticleVelocityType VelocityType; + + /** Full constructor: Bounds and bound modifier required + * @param _topology - The topology to get the global/local/other best + * @param _coeff - The constriction coefficient + * @param _weightUpdater - An eoWeightUpdater used to update the inertia weight + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _boundsModifier - An eoRealBoundModifier used to modify the bounds (for real bounds only). + * @param _gen - The eo random generator, default=rng + */ + eoConstrictedVariableWeightVelocity (eoTopology < POT > & _topology, + const VelocityType & _coeff, + eoWeightUpdater & _weightUpdater, + const VelocityType & _c1, + const VelocityType & _c2 , + eoRealVectorBounds & _bounds, + eoRealBoundModifier & _bndsModifier, + eoRng & _gen = rng): + topology(_topology), + coeff(_coeff), + weightUpdater(_weightUpdater), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(_bndsModifier), + gen(_gen){} + + + /** Constructor: No bound updater required <-> fixed bounds + * @param _topology - The topology to get the global/local/other best + * @param _coeff - The constriction coefficient + * @param _weightUpdater - An eoWeightUpdater used to update the inertia weight + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _gen - The eo random generator, default=rng + */ + eoConstrictedVariableWeightVelocity (eoTopology < POT > & _topology, + const VelocityType & _coeff, + eoWeightUpdater & _weightUpdater, + const VelocityType & _c1, + const VelocityType & _c2, + eoRealVectorBounds & _bounds, + eoRng & _gen = rng): + topology(_topology), + coeff(_coeff), + weightUpdater(_weightUpdater), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(dummyModifier), + gen(_gen){} + + + /** Constructor: Neither bounds nor bound updater required <-> free velocity + * @param _topology - The topology to get the global/local/other best* + * @param _coeff - The constriction coefficient + * @param _weightUpdater - An eoWeightUpdater used to update the inertia weight + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _gen - The eo random generator, default=rng + */ + eoConstrictedVariableWeightVelocity (eoTopology < POT > & _topology, + const VelocityType & _coeff, + eoWeightUpdater & _weightUpdater, + const VelocityType & _c1, + const VelocityType & _c2, + eoRng & _gen = rng): + topology(_topology), + coeff(_coeff), + weightUpdater(_weightUpdater), + c1 (_c1), + c2 (_c2), + bounds(*(new eoRealVectorNoBounds(0))), + bndsModifier(dummyModifier), + gen(_gen) + {} + + /** + * Evaluate the new velocities of the given particle. Need an indice to identify the particle + * into the topology. Steps are : + * - evaluate r1 and r2, the customed learning factors + * - adjust the size of the bounds (even if dummy) + * - update the weight with the weightUpdater (use the dummy updater if there's no updater provided) + * - modify the bounds with the bounds modifier (use the dummy modifier if there's no modifier provided) + * @param _po - A particle + * @param _indice - The indice (into the topology) of the given particle + */ + void operator () (POT & _po,unsigned _indice) + { + VelocityType r1; + VelocityType r2; + + VelocityType newVelocity; + + // cast the learning factors to VelocityType + r1 = (VelocityType) rng.uniform (1) * c1; + r2 = (VelocityType) rng.uniform (1) * c2; + + // need to resize the bounds even if there are dummy because of "isBounded" call + bounds.adjust_size(_po.size()); + + // update the inertia weight + weightUpdater(weight); + + // assign the new velocities + for (unsigned j = 0; j < _po.size (); j++) + { + newVelocity= coeff * (weight * _po.velocities[j] + r1 * (_po.bestPositions[j] - _po[j]) + r2 * (topology.best (_indice)[j] - _po[j])); + + /* modify the bounds */ + bndsModifier(bounds,j); + + /* check bounds */ + if (bounds.isMinBounded(j)) + newVelocity=(VelocityType)std::max(newVelocity,bounds.minimum(j)); + if (bounds.isMaxBounded(j)) + newVelocity=(VelocityType)std::min(newVelocity,bounds.maximum(j)); + + _po.velocities[j]=newVelocity; + } + } + + /** + * Update the neighborhood. + */ + void updateNeighborhood(POT & _po,unsigned _indice) + { + topology.updateNeighborhood(_po,_indice); + } + + + +protected: + eoTopology < POT > & topology; + + const VelocityType & coeff; // the fixed constriction coefficient + eoWeightUpdater & weightUpdater; // the updater used to make the weight evoluate + + const VelocityType & c1; // learning factor 1 + const VelocityType & c2; // learning factor 2 + + eoRealVectorBounds & bounds; // REAL bounds even if the velocity could be of another type. + eoRealBoundModifier & bndsModifier; + + VelocityType weight; + eoRng & gen; // the random generator + + // If the bound modifier doesn't need to be used, use the dummy instance + eoDummyRealBoundModifier dummyModifier; +}; + +#endif /*EOCONSTRICTEDVARIABLEWEIGHTVELOCITY_H*/ + diff --git a/eo/src/eoConstrictedVelocity.h b/eo/src/eoConstrictedVelocity.h new file mode 100644 index 00000000..904ea8d5 --- /dev/null +++ b/eo/src/eoConstrictedVelocity.h @@ -0,0 +1,191 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoConstrictedVelocity.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOCONSTRICTEDVELOCITY_H +#define EOCONSTRICTEDVELOCITY_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + + +/** Constricted velocity performer. Derivated from abstract eoVelocity, +* At step t+1 : v(t+1)= C * [ v(t) + c1*r1 * (xbest(t)-x(t)) + c2*r2 * (gbest(t) - x(t)) ] +* C is fixed for all the particles and all the generations. +* Default C = 2 * k / abs(2 - P - sqrt (P*(P-4))) +* (ci and C given;P=c1*r1 + c2*r2 ; Ri chosen at random * in [0;1]) +*/ +template < class POT > class eoConstrictedVelocity:public eoVelocity < POT > +{ + +public: + + /* + * Each element for the velocity evaluation is expected to be of type VelocityType. + */ + typedef typename POT::ParticleVelocityType VelocityType; + + /** Full constructor: Bounds and bound modifier required + * @param _topology - The topology to get the global/local/other best + * @param _coeff - The constriction coefficient + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _boundsModifier - An eoRealBoundModifier used to modify the bounds (for real bounds only). + * @param _gen - The eo random generator, default=rng + */ + eoConstrictedVelocity (eoTopology < POT > & _topology, + const VelocityType & _coeff, + const VelocityType & _c1, + const VelocityType & _c2 , + eoRealVectorBounds & _bounds, + eoRealBoundModifier & _bndsModifier, + eoRng & _gen = rng): + topology(_topology), + coeff(_coeff), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(_bndsModifier), + gen(_gen){} + + + /** Constructor: No bound updater required <-> fixed bounds + * @param _topology - The topology to get the global/local/other best + * @param _coeff - The constriction coefficient + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _gen - The eo random generator, default=rng + */ + eoConstrictedVelocity (eoTopology < POT > & _topology, + const VelocityType & _coeff, + const VelocityType & _c1, + const VelocityType & _c2, + eoRealVectorBounds & _bounds, + eoRng & _gen = rng): + topology(_topology), + coeff(_coeff), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(dummyModifier), + gen(_gen){} + + + /** Constructor: Neither bounds nor bound updater required <-> free velocity + * @param _topology - The topology to get the global/local/other best + * @param _coeff - The constriction coefficient + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _gen - The eo random generator, default=rng + */ + eoConstrictedVelocity (eoTopology < POT > & _topology, + const VelocityType & _coeff, + const VelocityType & _c1, + const VelocityType & _c2, + eoRng & _gen = rng): + topology(_topology), + coeff(_coeff), + c1 (_c1), + c2 (_c2), + bounds(*(new eoRealVectorNoBounds(0))), + bndsModifier(dummyModifier), + gen(_gen){} + + + /** + * Evaluate the new velocities of the given particle. Need an indice to identify the particle + * into the topology. Steps are : + * - evaluate r1 and r2, the customed learning factors + * - adjust the size of the bounds (even if dummy) + * - modify the bounds with the bounds modifier (use the dummy modifier if there's no modifier provided) + * @param _po - A particle + * @param _indice - The indice (into the topology) of the given particle + */ + void operator () (POT & _po,unsigned _indice) + { + VelocityType r1; + VelocityType r2; + + VelocityType newVelocity; + + // cast the learning factors to VelocityType + r1 = (VelocityType) rng.uniform (1) * c1; + r2 = (VelocityType) rng.uniform (1) * c2; + + // need to resize the bounds even if there are dummy because of "isBounded" call + bounds.adjust_size(_po.size()); + + // assign the new velocities + for (unsigned j = 0; j < _po.size (); j++) + { + newVelocity= coeff * (_po.velocities[j] + r1 * (_po.bestPositions[j] - _po[j]) + r2 * (topology.best (_indice)[j] - _po[j])); + + /* modify the bounds */ + bndsModifier(bounds,j); + + /* check bounds */ + if (bounds.isMinBounded(j)) + newVelocity=(VelocityType)std::max(newVelocity,bounds.minimum(j)); + if (bounds.isMaxBounded(j)) + newVelocity=(VelocityType)std::min(newVelocity,bounds.maximum(j)); + + _po.velocities[j]=newVelocity; + } + } + + /** + * Update the neighborhood of a particle. + */ + void updateNeighborhood(POT & _po,unsigned _indice) + { + topology.updateNeighborhood(_po,_indice); + } + + + +protected: + eoTopology < POT > & topology; + const VelocityType & c1; // learning factor 1 + const VelocityType & c2; // learning factor 2 + const VelocityType & coeff; // the fixed constriction coefficient + eoRng & gen; // the random generator + + eoRealVectorBounds & bounds; // REAL bounds even if the velocity could be of another type. + eoRealBoundModifier & bndsModifier; + + // If the bound modifier doesn't need to be used, use the dummy instance + eoDummyRealBoundModifier dummyModifier; +}; + + +#endif /*EOCONSTRICTEDVELOCITY_H */ + diff --git a/eo/src/eoDummyFlight.h b/eo/src/eoDummyFlight.h new file mode 100644 index 00000000..a1940315 --- /dev/null +++ b/eo/src/eoDummyFlight.h @@ -0,0 +1,51 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoDummyFlight.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EODUMMYFLIGHT_H +#define EODUMMYFLIGHT_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + + +/** +* A dummy flight that does nothing ! +*/ +template < class POT > class eoDummyFlight:public eoFlight < POT > +{ + +public: + + // Ctor + eoDummyFlight () {} + + /** + * Dummy move: do nothing + */ + void operator () (POT & _po1) {} +}; + + +#endif /*EODUMMYFLIGHT_H */ diff --git a/eo/src/eoEasyPSO.h b/eo/src/eoEasyPSO.h new file mode 100644 index 00000000..931194c1 --- /dev/null +++ b/eo/src/eoEasyPSO.h @@ -0,0 +1,129 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEasyPSO.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOEASYPSO_H +#define _EOEASYPSO_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + +/** An easy-to-use particle swarm algorithm; you can use any particle, +* any flight, any topology... The main steps are : +* (The population is expected to be already evaluated) +* - for each generation and each particle pi +* - evaluate the velocities +* -- perform the fligth of pi +* -- evaluate pi +* -- update the neighborhoods +*/ +template < class POT > class eoEasyPSO:public eoPSO < POT > +{ +public: + + /** Full constructor + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _velocity - An eoVelocity that defines how to compute the velocities + * @param _flight - An eoFlight that defines how to make the particle flying: that means how + * to modify the positions according to the velocities + */ + eoEasyPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + eoVelocity < POT > &_velocity, + eoFlight < POT > &_flight): + continuator (_continuator), + eval (_eval), + velocity (_velocity), + flight (_flight){} + + + /** Constructor without eoFlight. For special cases when the flight is performed withing the velocity. + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _velocity - An eoVelocity that defines how to compute the velocities + */ + eoEasyPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + eoVelocity < POT > &_velocity): + continuator (_continuator), + eval (_eval), + velocity (_velocity), + flight (dummyFlight){} + + + + /// Apply a few iteration of flight to the population (=swarm). + virtual void operator () (eoPop < POT > &_pop) + { + try + { + do + { + // loop over all the particles for the current iteration + for (unsigned idx = 0; idx < _pop.size (); idx++) + { + // perform velocity evaluation + velocity (_pop[idx],idx); + + // apply the flight + flight (_pop[idx]); + + // evaluate the position + eval (_pop[idx]); + + // update the topology (particle and local/global best(s)) + velocity.updateNeighborhood(_pop[idx],idx); + } + + }while (continuator (_pop)); + + } + catch (std::exception & e) + { + std::string s = e.what (); + s.append (" in eoEasyPSO"); + throw std::runtime_error (s); + } + + } + +private: + eoContinue < POT > &continuator; + eoEvalFunc < POT > &eval; + eoVelocity < POT > &velocity; + eoFlight < POT > &flight; + + // if the flight does not need to be used, use the dummy flight instance + eoDummyFlight dummyFlight; +}; + + +#endif /*_EOEASYPSO_H*/ diff --git a/eo/src/eoFixedInertiaWeightedVelocity.h b/eo/src/eoFixedInertiaWeightedVelocity.h new file mode 100644 index 00000000..6d748d18 --- /dev/null +++ b/eo/src/eoFixedInertiaWeightedVelocity.h @@ -0,0 +1,190 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoFixedInertiaWeightedVelocity.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOFIXEDINERTIAWEIGHTEDVELOCITY_H +#define EOFIXEDINERTIAWEIGHTEDVELOCITY_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + + +/** Inertia weight based velocity performer. Derivated from abstract eoVelocity, +* At step t+1 : v(t+1)= w * v(t) + c1*r1 * (xbest(t)-x(t)) + c2*r2 * (gbest(t) - x(t)) +* w is fixed for all the particles and all the generations. +* (ci and w given; Ri chosen at random * in [0;1]) +*/ +template < class POT > class eoFixedInertiaWeightedVelocity:public eoVelocity < POT > +{ + +public: + + /* + * Each element for the velocity evaluation is expected to be of type VelocityType. + */ + typedef typename POT::ParticleVelocityType VelocityType; + + /** Full constructor: Bounds and bound modifier required + * @param _topology - The topology to get the global/local/other best + * @param _weight - The weight with type VelocityType + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _boundsModifier - An eoRealBoundModifier used to modify the bounds (for real bounds only). + * @param _gen - The eo random generator, default=rng + */ + eoFixedInertiaWeightedVelocity (eoTopology < POT > & _topology, + const VelocityType & _weight, + const VelocityType & _c1, + const VelocityType & _c2 , + eoRealVectorBounds & _bounds, + eoRealBoundModifier & _bndsModifier, + eoRng & _gen = rng): + topology(_topology), + weight(_weight), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(_bndsModifier), + gen(_gen){} + + + /** Constructor: No bound updater required <-> fixed bounds + * @param _topology - The topology to get the global/local/other best + * @param _weight - The weight with type VelocityType + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _gen - The eo random generator, default=rng + */ + eoFixedInertiaWeightedVelocity (eoTopology < POT > & _topology, + const VelocityType & _weight, + const VelocityType & _c1, + const VelocityType & _c2, + eoRealVectorBounds & _bounds, + eoRng & _gen = rng): + topology(_topology), + weight(_weight), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(dummyModifier), + gen(_gen){} + + + /** Constructor: Neither bounds nor bound updater required <-> free velocity + * @param _topology - The topology to get the global/local/other best + * @param _weight - The weight with type VelocityType + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _gen - The eo random generator, default=rng + */ + eoFixedInertiaWeightedVelocity (eoTopology < POT > & _topology, + const VelocityType & _weight, + const VelocityType & _c1, + const VelocityType & _c2, + eoRng & _gen = rng): + topology(_topology), + weight(_weight), + c1 (_c1), + c2 (_c2), + bounds(*(new eoRealVectorNoBounds(0))), + bndsModifier(dummyModifier), + gen(_gen) + {} + + /** + * Evaluate the new velocities of the given particle. Need an indice to identify the particle + * into the topology. Steps are : + * - evaluate r1 and r2, the customed learning factors + * - adjust the size of the bounds (even if dummy) + * - modify the bounds with the bounds modifier (use the dummy modifier if there's no modifier provided) + * @param _po - A particle + * @param _indice - The indice (into the topology) of the given particle + */ + void operator () (POT & _po,unsigned _indice) + { + VelocityType r1; + VelocityType r2; + + VelocityType newVelocity; + + // cast the learning factors to VelocityType + r1 = (VelocityType) rng.uniform (1) * c1; + r2 = (VelocityType) rng.uniform (1) * c2; + + // need to resize the bounds even if there are dummy because of "isBounded" call + bounds.adjust_size(_po.size()); + + // assign the new velocities + for (unsigned j = 0; j < _po.size (); j++) + { + newVelocity= weight * _po.velocities[j] + r1 * (_po.bestPositions[j] - _po[j]) + r2 * (topology.best (_indice)[j] - _po[j]); + + /* modify the bounds */ + bndsModifier(bounds,j); + + /* check bounds */ + if (bounds.isMinBounded(j)) + newVelocity=(VelocityType)std::max(newVelocity,bounds.minimum(j)); + if (bounds.isMaxBounded(j)) + newVelocity=(VelocityType)std::min(newVelocity,bounds.maximum(j)); + + _po.velocities[j]=newVelocity; + } + } + + /** + * Update the neighborhood. + */ + void updateNeighborhood(POT & _po,unsigned _indice) + { + topology.updateNeighborhood(_po,_indice); + } + + + +protected: + eoTopology < POT > & topology; + const VelocityType & c1; // learning factor 1 + const VelocityType & c2; // learning factor 2 + const VelocityType & weight; // the fixed weight + eoRng & gen; // the random generator + + eoRealVectorBounds & bounds; // REAL bounds even if the velocity could be of another type. + eoRealBoundModifier & bndsModifier; + + // If the bound modifier doesn't need to be used, use the dummy instance + eoDummyRealBoundModifier dummyModifier; +}; + + +#endif /*EOFIXEDINERTIAWEIGHTEDVELOCITY_H */ + diff --git a/eo/src/eoFlight.h b/eo/src/eoFlight.h new file mode 100644 index 00000000..78969050 --- /dev/null +++ b/eo/src/eoFlight.h @@ -0,0 +1,54 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoFlight.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOFLIGHT_H +#define EOFLIGHT_H + +//----------------------------------------------------------------------------- +#include +#include +//----------------------------------------------------------------------------- + +/** Abstract class for PSO flight. +* All the flights must derivated from eoFlight. +*/ + +template < class POT > class eoFlight:public eoUF < POT &, void > +{ +public: + + /** + * Apply the flight to a whole population. + */ + virtual void apply (eoPop < POT > &_pop) + { + for (unsigned i = 0; i < _pop.size (); i++) + { + operator ()(_pop[i]); + } + + } +}; + +#endif /*EOFLIGHT_H */ diff --git a/eo/src/eoGaussRealWeightUp.h b/eo/src/eoGaussRealWeightUp.h new file mode 100644 index 00000000..05d33e1c --- /dev/null +++ b/eo/src/eoGaussRealWeightUp.h @@ -0,0 +1,68 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoGaussRealWeightUp.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOGAUSSREALWEIGHTUP_H +#define EOGAUSSREALWEIGHTUP_H + +//----------------------------------------------------------------------------- +#include +#include +//----------------------------------------------------------------------------- + + +/** + * Update an inertia weight by assigning it a Gaussian randomized value. + */ +class eoGaussRealWeightUp:public eoWeightUpdater +{ +public: + + /** + * Default constructor + * @param _mean - Mean for Gaussian distribution + * @param _stdev - Standard deviation for Gaussian distribution + */ + eoGaussRealWeightUp( + double _mean=0, + double _stdev=1.0 + ):mean(_mean),stdev(_stdev){} + + /** + * Assign Gaussian deviation to _weight + * @param _weight - The modified weight as a double + */ + void operator() (double & _weight) + { + _weight=rng.normal(mean,stdev); + } + + +protected: + double mean,stdev; + +}; + + + +#endif/*EOGAUSSREALWEIGHTUP_H*/ diff --git a/eo/src/eoLSPSO.h b/eo/src/eoLSPSO.h new file mode 100644 index 00000000..adfe1112 --- /dev/null +++ b/eo/src/eoLSPSO.h @@ -0,0 +1,184 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoLSPSO.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOLSPSO_H +#define _EOLSPSO_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + +/** + * A Linear ("L"inear topology) Standard ("S"tandard velocity) PSO. + * You can use it with or without bounds on the velocity. + * No bound for the flight (no bounds for the positions). + * + */ +template < class POT > class eoLSPSO:public eoPSO < POT > +{ +public: + + + typedef typename POT::ParticleVelocityType VelocityType; + + /** Full constructor + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _neighborhoodSize - The size of each neighborhood of the linear topology + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _boundsModifier - An eoRealBoundModifier used to modify the bounds (for real bounds only) + */ + eoLSPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + const VelocityType & _c1, + const VelocityType & _c2 , + const unsigned _neighborhoodSize, + eoRealVectorBounds & _bounds, + eoRealBoundModifier & _bndsModifier): + continuator (_continuator), + eval (_eval), + topology(eoLinearTopology(_neighborhoodSize)), + velocity(eoStandardVelocity(topology,_c1,_c2,_bounds,_bndsModifier)), + neighborhoodSize(_neighborhoodSize), + bounds(_bounds), + boundsModifier(_bndsModifier) + {} + + /** Constructor without bound modifier. + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _neighborhoodSize - The size of each neighborhood of the linear topology + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + */ + eoLSPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + const VelocityType & _c1, + const VelocityType & _c2 , + const unsigned _neighborhoodSize, + eoRealVectorBounds & _bounds): + continuator (_continuator), + eval (_eval), + topology(eoLinearTopology(_neighborhoodSize)), + velocity(eoStandardVelocity(topology,_c1,_c2,_bounds)), + neighborhoodSize(_neighborhoodSize), + bounds(_bounds), + boundsModifier(dummyModifier) + {} + + + /** Constructor without bounds nor bound modifier. + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _neighborhoodSize - The size of each neighborhood of the linear topology + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + */ + eoLSPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + const VelocityType & _c1, + const VelocityType & _c2, + const unsigned _neighborhoodSize): + continuator (_continuator), + eval (_eval), + topology(eoLinearTopology(_neighborhoodSize)), + velocity(eoStandardVelocity(topology,_c1,_c2)), + neighborhoodSize(_neighborhoodSize), + bounds(*(new eoRealVectorNoBounds(0))), + boundsModifier(dummyModifier) + {} + + + /// Apply a few iteration of flight to the population (=swarm). + virtual void operator () (eoPop < POT > &_pop) + { + try + { + // setup the topology (done once) + topology.setup(_pop); + + do + { + // loop over all the particles for the current iteration + for (unsigned idx = 0; idx < _pop.size (); idx++) + { + // perform velocity evaluation + velocity (_pop[idx],idx); + + // apply the flight + flight (_pop[idx]); + + // evaluate the position + eval (_pop[idx]); + + // update the topology (particle and the global bests) + velocity.updateNeighborhood(_pop[idx],idx); + } + + } while (continuator (_pop)); + + }catch (std::exception & e) + { + std::string s = e.what (); + s.append (" in eoLSPSO"); + throw std::runtime_error (s); + } + + } + +protected: + eoContinue < POT > &continuator; + eoEvalFunc < POT > &eval; + + eoStandardVelocity < POT > velocity; + eoStandardFlight < POT > flight; + + const unsigned neighborhoodSize; + eoLinearTopology topology; + + eoRealVectorBounds bounds; // REAL bounds even if the velocity could be of another type. + eoRealBoundModifier & boundsModifier; + + // If the bound modifier doesn't need to be used, use the dummy instance + eoDummyRealBoundModifier dummyModifier; + +}; + + +#endif /*_EOLSPSO_H*/ diff --git a/eo/src/eoLinearDecreasingWeightUp.h b/eo/src/eoLinearDecreasingWeightUp.h new file mode 100644 index 00000000..d06bda8f --- /dev/null +++ b/eo/src/eoLinearDecreasingWeightUp.h @@ -0,0 +1,75 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoLinearDecreasingWeightUp.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOLINEARDECREASINGWEIGHTUP_H +#define EOLINEARDECREASINGWEIGHTUP_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + + +/** + * Linear (inertia) weight updater. Update a weight according to: + * w(t)=(w(0)-w(Nt))*(Nt -t)/Nt + w(Nt) where + * t is the current generation/event + * Nt is the total number of generations/event + * w(0) is the initial weight + * w(Nt) is the last inertia weight + */ +template class eoLinearDecreasingWeightUp:public eoWeightUpdater +{ +public: + + /** + * Ctor + */ + eoLinearDecreasingWeightUp( + const StopCriteriaType & _stop, + const WeightType & _initialValue, + const WeightType & _finalValue, + eoValueParam & _counter): + stop(_stop), + initialValue(_initialValue), + finalValue(_finalValue), + counter(_counter){} + + /** + * Update the given weight + */ + void operator() (WeightType & _weight) + { + _weight=(initialValue-finalValue)* (WeightType)(stop-counter.value())/(WeightType)stop + finalValue; + + } + +protected: + const StopCriteriaType & stop; + const WeightType & initialValue,finalValue; + eoValueParam & counter; // a counter of the number of past events (should say "generations") +}; + + + +#endif/*EOLINEARDECREASINGWEIGHTUP_H*/ diff --git a/eo/src/eoLinearTopology.h b/eo/src/eoLinearTopology.h new file mode 100644 index 00000000..ccae6dd9 --- /dev/null +++ b/eo/src/eoLinearTopology.h @@ -0,0 +1,199 @@ + +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoLinearTopology.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOLINEARTOPOLOGY_H_ +#define EOLINEARTOPOLOGY_H_ + +//----------------------------------------------------------------------------- +#include +#include +#include +//----------------------------------------------------------------------------- + + +/** + * One of the local best strategies. Each particle has a fixed number of neighbours, ans + * the neighborhood is social. + * The topology is never modified during the flight. + */ +template < class POT > class eoLinearTopology:public eoTopology < + POT > +{ + +public: + + /** + * Build the topology made of _neighborhoodSize neighborhoods. + * @param _neighborhoods - The size of each neighborhood. + */ + eoLinearTopology (unsigned _neighborhoodSize):neighborhoodSize (_neighborhoodSize),isSetup(false){} + + + /** + * Build the neighborhoods contained in the topology. + * @param _pop - The population used to build the neighborhoods. + * If it remains several particle (because _pop.size()%neighborhoodSize !=0), there are inserted + * in the last neighborhood. So it may be possible to have a bigger neighborhood. + */ + void setup(const eoPop & _pop) + { + if (!isSetup) + { + // consitency check + if (neighborhoodSize >= _pop.size()){ + std::string s; + s.append (" Invalid neighborhood size in eoLinearTopology "); + throw std::runtime_error (s); + } + + unsigned howManyNeighborhood=_pop.size()/ neighborhoodSize; + + // build all the neighborhoods + for (unsigned i=0;i< howManyNeighborhood;i++) + { + eoSocialNeighborhood currentNghd; + + currentNghd.best(_pop[i*neighborhoodSize]); + for (unsigned k=i*neighborhoodSize;k < neighborhoodSize*(i+1);k++) + { + currentNghd.put(k); + if (_pop[k].fitness() > currentNghd.best().fitness()) + currentNghd.best(_pop[k]); + } + neighborhoods.push_back(currentNghd); + } + + // assign the last neighborhood to the remaining particles + if (_pop.size()%neighborhoodSize !=0) + { + for (unsigned z=_pop.size()-1;z >= (_pop.size()-_pop.size()%neighborhoodSize);z--){ + neighborhoods.back().put(z); + + if (_pop[z].fitness() > neighborhoods.back().best().fitness()) + neighborhoods.back().best(_pop[z]); + } + } + + isSetup=true; + } + else + { + // Should activate this part ? + /* + std::string s; + s.append (" Linear topology already setup in eoLinearTopology"); + throw std::runtime_error (s); + */ + } + + } + + + /** + * Retrieve the neighboorhood of a particle. + * @return _indice - The particle indice (in the population) + */ + unsigned retrieveNeighborhoodByIndice(unsigned _indice) + { + unsigned i=0; + for (i=0;i< neighborhoods.size();i++) + { + if (neighborhoods[i].contains(_indice)) + { + return i; + } + } + return i; + } + + + /** + * Update the neighborhood: update the particle's best fitness and the best particle + * of the corresponding neighborhood. + */ + void updateNeighborhood(POT & _po,unsigned _indice) + { + // update the best fitness of the particle + if (_po.fitness() > _po.best()) + { + _po.best(_po.fitness()); + } + + // update the best in its neighborhood + unsigned theGoodNhbd= retrieveNeighborhoodByIndice(_indice); + if (_po.fitness() > neighborhoods[theGoodNhbd].best().fitness()) + { + neighborhoods[theGoodNhbd].best(_po); + } + } + + + /** + * Return the best informative of a particle. Could be itself. + * @param _indice - The indice of a particle in the population + * @return POT & - The best particle in the neighborhood of the particle whose indice is _indice + */ + POT & best (unsigned _indice) + { + unsigned theGoodNhbd= retrieveNeighborhoodByIndice(_indice); + + return (neighborhoods[theGoodNhbd].best()); + } + + + /** + * Print the structure of the topology on the standrad output. + */ + void printOn() + { + for (unsigned i=0;i< neighborhoods.size();i++) + { + std::cout << "{ " ; + for (unsigned j=0;j< neighborhoods[i].size();j++) + { + std::cout << neighborhoods[i].get(j) << " "; + } + std::cout << "}" << std::endl; + } + } + + +protected: + std::vector > neighborhoods; + unsigned neighborhoodSize; // the size of each neighborhood + + bool isSetup; + +}; + +#endif /*EOLINEARTOPOLOGY_H_ */ + + + + + + + + diff --git a/eo/src/eoNeighborhood.h b/eo/src/eoNeighborhood.h new file mode 100644 index 00000000..79857838 --- /dev/null +++ b/eo/src/eoNeighborhood.h @@ -0,0 +1,66 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoNeighborhood.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EONEIGHBORHOOD_H_ +#define EONEIGHBORHOOD_H_ + + +/** + * Abstract class for neighborboods. Used for particle swarm optimization + * topology strategies. Can be social or physical. + */ +template < class POT > class eoNeighborhood +{ +public: + + virtual void put(unsigned _oneIndice)=0; + + virtual bool contains(unsigned _oneIndice)=0; + + virtual unsigned size()=0; + + virtual unsigned get(unsigned _index)=0; + + virtual POT & best()=0; + + virtual void best(POT _particle)=0; + + /// Virtual dtor + virtual ~eoNeighborhood() {}; + +}; + + +#endif /* EONEIGHBORHOOD_H_ */ + + + + + + + + + + + diff --git a/eo/src/eoPSO.h b/eo/src/eoPSO.h new file mode 100644 index 00000000..fa53b93e --- /dev/null +++ b/eo/src/eoPSO.h @@ -0,0 +1,40 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoPSO.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOPSO_H +#define _EOPSO_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + +/** + This is a generic class for particle swarm algorithms. There + is only one operator defined, which takes a population and does stuff to + it. It needn't be a complete algorithm, can be also a step of an + algorithm. Only used for mono-objective cases. +*/ +template < class POT > class eoPSO:public eoAlgo < POT >{}; + +#endif /*_EOPSO_H*/ diff --git a/eo/src/eoParticleBestInit.h b/eo/src/eoParticleBestInit.h new file mode 100644 index 00000000..79d78ed3 --- /dev/null +++ b/eo/src/eoParticleBestInit.h @@ -0,0 +1,77 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoParticleBestInit.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOPARTICLEBESTINIT_H +#define _EOPARTICLEBESTINIT_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + +/** + * Abstract class for particle best position initialization. + */ + +template < class POT > class eoParticleBestInit:public eoUF < POT &, void > +{ +public: + + /** Apply the initialization to a whole given population */ + virtual void apply (eoPop < POT > &_pop) + { + for (unsigned i = 0; i < _pop.size (); i++) + { + operator ()(_pop[i]); + } + + } + +}; + +/** + * Initializes the best positions of a particle as its current positions and set the + * particle best fitness. + */ +template < class POT > class eoFirstIsBestInit:public eoParticleBestInit +{ + +public: + + /** Default CTor */ + eoFirstIsBestInit (){} + + void operator () (POT & _po1) + { + for (unsigned i = 0; i < _po1.size (); i++) + _po1.bestPositions[i] = _po1[i]; + + // set the fitness + _po1.best(_po1.fitness()); + } + +}; + +#endif /*_EOPARTICLEBESTINIT_H */ + + diff --git a/eo/src/eoRandomRealWeightUp.h b/eo/src/eoRandomRealWeightUp.h new file mode 100644 index 00000000..a2987df3 --- /dev/null +++ b/eo/src/eoRandomRealWeightUp.h @@ -0,0 +1,76 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoRandomRealWeightUp.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EORANDOMREALWEIGHTUP_H +#define EORANDOMREALWEIGHTUP_H + +//----------------------------------------------------------------------------- +#include +#include +//----------------------------------------------------------------------------- + +/** + * Update an inertia weight by assigning it an (uniform) random value. + */ +class eoRandomRealWeightUp:public eoWeightUpdater +{ +public: + + /** + * Default constructor + * @param _min - The minimum bound for the weight + * @param _max - The maximum bound for the weight + */ + eoRandomRealWeightUp( + double _min, + double _max + ):min(_min),max(_max) + { + // consistency check + if (min > max) + { + std::string s; + s.append (" min > max in eoRandomRealWeightUp"); + throw std::runtime_error (s); + } + } + + /** + * Generate an real random number in [min,max] and assign it to _weight + * @param _weight - The assigned (real) weight + */ + void operator() (double & _weight) + { + _weight=rng.uniform(max-min)+min; + } + + +protected: + double min,max; + +}; + + + +#endif/*EORANDOMREALWEIGHTUP_H*/ diff --git a/eo/src/eoRealBoundModifier.h b/eo/src/eoRealBoundModifier.h new file mode 100644 index 00000000..b309a483 --- /dev/null +++ b/eo/src/eoRealBoundModifier.h @@ -0,0 +1,97 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoRealBoundModifier.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOREALBOUNDMODIFIER_H +#define EOREALBOUNDMODIFIER_H + +//----------------------------------------------------------------------------- +#include +#include +//----------------------------------------------------------------------------- + +/** + * Abstract class for eoRealVectorBounds modifier. + * Used to modify the bounds included into the eoRealVectorBounds object. + */ +class eoRealBoundModifier: public eoBF < eoRealBaseVectorBounds &,unsigned,void > {}; + + +/** + * An eoRealBoundModifier that modify nothing ! + */ +class eoDummyRealBoundModifier: public eoRealBoundModifier +{ +public: + + eoDummyRealBoundModifier (){} + + void operator() (eoRealBaseVectorBounds & _bnds,unsigned _i){} +}; + + + +/** + * Modify an eoReal(Base)VectorBounds : + * At iteration t, the interval I(t)=[min,max] is updated as: + * I(t)=[min,(1-(t/Nt)^alpha)*max] where + * - t, the current iteration, is given with an eoValueParam + * - Nt is the stopping criteria <=> the total number of iterations + * - alpha a coefficient + * + */ +class eoExpDecayingBoundModifier: public eoRealBoundModifier +{ +public: + + /** + * Constructor + * @param _stopCriteria - The total number of iterations + * @param _alpha + * @param _genCounter - An eoValueParam that gives the current iteration + */ + eoExpDecayingBoundModifier (unsigned _stopCriteria, + double _alpha, + eoValueParam & _genCounter): + stopCriteria(_stopCriteria), + alpha(_alpha), + genCounter(_genCounter){} + + + void operator() (eoRealBaseVectorBounds & _bnds,unsigned _i) + { + double newMaxBound=(1-pow((double)genCounter.value()/stopCriteria,alpha))*_bnds.maximum(_i); + + // should delete the old eoRealBounds ? + _bnds[_i]=new eoRealInterval(_bnds.minimum(_i),std::max(_bnds.minimum(_i),newMaxBound)); + } + + +protected: + unsigned stopCriteria; + double alpha; + eoValueParam & genCounter; + +}; + +#endif/*EOREALBOUNDMODIFIER_H*/ diff --git a/eo/src/eoRealParticle.h b/eo/src/eoRealParticle.h new file mode 100644 index 00000000..cbf8a35d --- /dev/null +++ b/eo/src/eoRealParticle.h @@ -0,0 +1,47 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoRealParticle.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOREALPARTICLE_H +#define _EOREALPARTICLE_H + + +#include + + +/** eoRealParticle: Implementation of a real-coded particle. Positions, velocities and best positions are real-coded. +*/ +template < class FitT> class eoRealParticle: public eoVectorParticle + +{ +public: + + eoRealParticle(unsigned size = 0, double positions = 0.0,double velocities = 0.0,double bestPositions = 0.0): eoVectorParticle (size, positions,velocities,bestPositions) {} + + virtual std::string className() const + { + return "eoRealParticle"; + } +}; + +#endif /*_EOREALPARTICLE_H*/ diff --git a/eo/src/eoSSPSO.h b/eo/src/eoSSPSO.h new file mode 100644 index 00000000..028bfa10 --- /dev/null +++ b/eo/src/eoSSPSO.h @@ -0,0 +1,168 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoSSPSO.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOSSPSO_H +#define _EOSSPSO_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + +/** + * A Star ("S"tar topology) Standard ("S"tandard velocity) PSO. + * You can use it with or without bounds on the velocity. + * No bound for the flight (no bounds for the positions). + * + */ +template < class POT > class eoSSPSO:public eoPSO < POT > +{ +public: + + + typedef typename POT::ParticleVelocityType VelocityType; + + /** Full constructor + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _boundsModifier - An eoRealBoundModifier used to modify the bounds (for real bounds only) + */ + eoSSPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + const VelocityType & _c1, + const VelocityType & _c2 , + eoRealVectorBounds & _bounds, + eoRealBoundModifier & _bndsModifier): + continuator (_continuator), + eval (_eval), + velocity(eoStandardVelocity(topology,_c1,_c2,_bounds,_bndsModifier)), + bounds(_bounds), + boundsModifier(_bndsModifier) + {} + + /** Constructor without bound modifier. + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + */ + eoSSPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + const VelocityType & _c1, + const VelocityType & _c2 , + eoRealVectorBounds & _bounds): + continuator (_continuator), + eval (_eval), + velocity(eoStandardVelocity(topology,_c1,_c2,_bounds)), + bounds(_bounds), + boundsModifier(dummyModifier) + {} + + + /** Constructor without bounds nor bound modifier. + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + */ + eoSSPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + const VelocityType & _c1, + const VelocityType & _c2): + continuator (_continuator), + eval (_eval), + velocity(eoStandardVelocity(topology,_c1,_c2)), + bounds(*(new eoRealVectorNoBounds(0))), + boundsModifier(dummyModifier) + {} + + + /// Apply a few iteration of flight to the population (=swarm). + virtual void operator () (eoPop < POT > &_pop) + { + try + { + // setup the topology (done once) + topology.setup(_pop); + + do + { + // loop over all the particles for the current iteration + for (unsigned idx = 0; idx < _pop.size (); idx++) + { + // perform velocity evaluation + velocity (_pop[idx],idx); + + // apply the flight + flight (_pop[idx]); + + // evaluate the position + eval (_pop[idx]); + + // update the topology (particle and the global bests) + velocity.updateNeighborhood(_pop[idx],idx); + } + } while (continuator (_pop)); + + }catch (std::exception & e) + { + std::string s = e.what (); + s.append (" in eoSSPSO"); + throw std::runtime_error (s); + } + } + +protected: + eoContinue < POT > &continuator; + eoEvalFunc < POT > &eval; + + eoStandardVelocity < POT > velocity; + eoStandardFlight < POT > flight; + eoStarTopology topology; + + eoRealVectorBounds bounds; // REAL bounds even if the velocity could be of another type. + eoRealBoundModifier & boundsModifier; + + // If the bound modifier doesn't need to be used, use the dummy instance + eoDummyRealBoundModifier dummyModifier; + +}; + + +#endif /*_EOSSPSO_H*/ diff --git a/eo/src/eoSigBinaryFlight.h b/eo/src/eoSigBinaryFlight.h new file mode 100644 index 00000000..d507e538 --- /dev/null +++ b/eo/src/eoSigBinaryFlight.h @@ -0,0 +1,86 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoSigBinaryFlight.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOSIGBINARYFLIGHT_H +#define EOSIGBINARYFLIGHT_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + + + +/** + * Binary flight based on the sigmoid function. Velocities are expected to be "double" + * Consider Pi to be the i-th position of a particle and Vi to be the i-th velocity of the same particle : + * if rand[0;1] < sig(Vi) (Vi <=> double) + * Pi=1 + * else + * Pi=0 + */ +template < class POT > class eoSigBinaryFlight:public eoBinaryFlight < POT > +{ + +public: + + /** + * Constructor. + */ + eoSigBinaryFlight (){} + + + /** + * Sigmoid function + */ + double sigmoid( double _value) + { + return(1/(1+ exp(- _value))); + + } + + /** + * Apply the sigmoid binary flight to a particle. + * + */ + void operator () (POT & _po) + { + + for (unsigned j = 0; j < _po.size (); j++) + { + double sigma=rng.uniform(1); + + if (sigma < sigmoid(_po.velocities[j])) + _po[j]=1; + else + _po[j]=0; + } + + // invalidate the fitness because the positions have changed + _po.invalidate(); + } +}; + + + +#endif /*EOSIGBINARYFLIGHT_H */ diff --git a/eo/src/eoSocialNeighborhood.h b/eo/src/eoSocialNeighborhood.h new file mode 100644 index 00000000..3c4aae45 --- /dev/null +++ b/eo/src/eoSocialNeighborhood.h @@ -0,0 +1,134 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoSocialNeighborhood.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOSOCIALNEIGHBORHOOD_H_ +#define EOSOCIALNEIGHBORHOOD_H_ + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + +/** + * Derivated from eoNeighborhood. Just takes relationships into account. + * The neighborhood is defined as a list of indices corresponding to particles. + * Also contains ONE particle considered as the best of the neighborhood. + */ +template < class POT > class eoSocialNeighborhood : public eoNeighborhood +{ +public: + + eoSocialNeighborhood(){} + + /** + * Put a particle (identified by its indice in its population) in the neighborhood. + * @param _oneIndice - The indice of the particle in its population. + */ + void put(unsigned _oneIndice) + { + indicesList.push_back(_oneIndice); + } + + /** + * Return true if the neighborhood contains the indice (= that means "contains the + * particle whose indice is _oneIndice") + * @param _oneIndice - The indice of the particle in its population. + */ + bool contains(unsigned _oneIndice) + { + for (unsigned i=0;i< indicesList.size();i++) + { + if (indicesList[i]==_oneIndice) + return true; + } + return false; + } + + /** + * Return the list of particle indices as a vector. + */ + std::vector getInformatives() + { + return indicesList; + } + + /** + * Return the size of the neighborhood. + */ + unsigned size() + { + return indicesList.size(); + + } + + /** + * Return the "_index-th" particle of the neighborhood. + * Throw an exception if its not contained in the neighborhood. + */ + unsigned get(unsigned _index) + { + if (_index < size()) + return indicesList[_index]; + else{ + std::string s; + s.append (" Invalid indice in eoSocialNeighborhood "); + throw std::runtime_error (s); + } + } + + /** + * Return the best particle of the neighborhood. + * The topology is expected to get it. + */ + POT & best() + { + return lBest; + } + + /** + * Set the best particle of the neighborhood. + * The topology is expected to set it. + */ + void best(POT _particle) + { + lBest=_particle; + } + +protected: + std::vector indicesList; // The list of particles as a vector of indices + POT lBest; // the best particle of the neighborhood +}; + + +#endif /* EOSOCIALNEIGHBORHOOD_H_ */ + + + + + + + + + + + diff --git a/eo/src/eoStandardFlight.h b/eo/src/eoStandardFlight.h new file mode 100644 index 00000000..31a0dad2 --- /dev/null +++ b/eo/src/eoStandardFlight.h @@ -0,0 +1,107 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoStandardFlight.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOSTANDARDFLIGHT_H +#define EOSTANDARDFLIGHT_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + + + +/** Standard PSO flight. Derivated from abstract eoFlight, + * just adds the velocities to the current position of the particle + * and invalidates its fitness + */ +template < class POT > class eoStandardFlight:public eoFlight < POT > +{ + +public: + + /* + * Each element for the postion evaluation is expected to be of type PositionType. + */ + typedef typename POT::AtomType PositionType; + + + /** Constructor without bounds. + * + */ + eoStandardFlight ():bnds (*(new eoRealVectorNoBounds(0))){} + + + /** Constructor for continuous flight with real bounds: expects a eoRealVectorBounds object for bound + * control. + * @param _bounds - An eoRealVectorBounds + */ + eoStandardFlight (eoRealVectorBounds & _bounds):bnds (_bounds){} + + + /** Constructor for continuous flight with real bounds: expects a min and a + * max to build the same real bounds for all the positions. + * WARNING: _min and max MUST be double as the position type + * @param _dim - The dimension of the bounds = the dimension of the position + * @param _min - The lower bound to use for all the positions + * @param _max - The upper bound to use for all the positions + */ + eoStandardFlight (const unsigned _dim,const double & _min,const double & _max ):bnds (*(new eoRealVectorBounds(_dim,_min,_max))){} + + + /** + * Apply the standard flight to a particle : position:=position + velocity + * and ... invalidates the particle's fitness + */ + void operator () (POT & _po) + { + // need to resize the bounds even if there are dummy because of "isBounded" call + bnds.adjust_size(_po.size()); + + for (unsigned j = 0; j < _po.size (); j++) + { + PositionType newPosition; + + // tmp position + newPosition = _po[j] + _po.velocities[j]; + + /* check bounds */ + if (bnds.isMinBounded(j)) + newPosition=std::max(newPosition,bnds.minimum(j)); + if (bnds.isMaxBounded(j)) + newPosition=std::min(newPosition,bnds.maximum(j)); + + _po[j]=newPosition; + } + // invalidate the fitness because the positions have changed + _po.invalidate(); + } + +protected: + eoRealVectorBounds & bnds; +}; + + + + +#endif /*EOSTANDARDFLIGHT_H */ diff --git a/eo/src/eoStandardVelocity.h b/eo/src/eoStandardVelocity.h new file mode 100644 index 00000000..70d60f24 --- /dev/null +++ b/eo/src/eoStandardVelocity.h @@ -0,0 +1,175 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoStandardVelocity.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOSTANDARDVELOCITY_H +#define EOSTANDARDVELOCITY_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + + +/** Standard PSO velocity performer. Derivated from abstract eoVelocity, +* At step t: v(t+1)= v(t) + c1*r1* ( xbest(t)-x(t) ) + c2*r2* ( gbest(t) - x(t) ) +* (ci given and Ri chosen at random in [0;1]). +*/ +template < class POT > class eoStandardVelocity:public eoVelocity < POT > +{ + +public: + + /* + * Each element for the velocity evaluation is expected to be of type VelocityType. + */ + typedef typename POT::ParticleVelocityType VelocityType; + + /** Full constructor: Bounds and bound modifier required + * @param _topology - The topology to get the global/local/other best + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _boundsModifier - An eoRealBoundModifier used to modify the bounds (for real bounds only). + * @param _gen - The eo random generator, default=rng + */ + eoStandardVelocity (eoTopology < POT > & _topology, + const VelocityType & _c1, + const VelocityType & _c2 , + eoRealVectorBounds & _bounds, + eoRealBoundModifier & _bndsModifier, + eoRng & _gen = rng): + topology(_topology), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(_bndsModifier), + gen(_gen){} + + + /** Constructor: No bound updater required <-> fixed bounds + * @param _topology - The topology to get the global/local/other best + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _gen - The eo random generator, default=rng + */ + eoStandardVelocity (eoTopology < POT > & _topology, + const VelocityType & _c1, + const VelocityType & _c2, + eoRealVectorBounds & _bounds, + eoRng & _gen = rng): + topology(_topology), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(dummyModifier), + gen(_gen){} + + + /** Constructor: Neither bounds nor bound updater required <-> free velocity + * @param _topology - The topology to get the global/local/other best + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _gen - The eo random generator, default=rng + */ + eoStandardVelocity (eoTopology < POT > & _topology, + const VelocityType & _c1, + const VelocityType & _c2, + eoRng & _gen = rng): + topology(_topology), + c1 (_c1), + c2 (_c2), + bounds(*(new eoRealVectorNoBounds(0))), + bndsModifier(dummyModifier), + gen(_gen) + {} + + + /** + * Evaluate the new velocities of the given particle. Need an indice to identify the particle + * into the topology. + * @param _po - A particle + * @param _indice - The indice (into the topology) of the given particle + */ + void operator () (POT & _po,unsigned _indice) + { + VelocityType r1; + VelocityType r2; + + VelocityType newVelocity; + + // cast the learning factors to VelocityType + r1 = (VelocityType) rng.uniform (1) * c1; + r2 = (VelocityType) rng.uniform (1) * c2; + + // need to resize the bounds even if there are dummy because of "isBounded" call + bounds.adjust_size(_po.size()); + + // assign the new velocities + for (unsigned j = 0; j < _po.size (); j++) + { + newVelocity= _po.velocities[j] + r1 * (_po.bestPositions[j] - _po[j]) + r2 * (topology.best (_indice)[j] - _po[j]); + + /* check bounds */ + if (bounds.isMinBounded(j)) + newVelocity=std::max(newVelocity,bounds.minimum(j)); + if (bounds.isMaxBounded(j)) + newVelocity=std::min(newVelocity,bounds.maximum(j)); + + _po.velocities[j]=newVelocity; + } + } + + /** + * Update the neighborhood. + */ + void updateNeighborhood(POT & _po,unsigned _indice) + { + topology.updateNeighborhood(_po,_indice); + } + + +protected: + eoTopology < POT > & topology; + const VelocityType & c1; // learning factor 1 + const VelocityType & c2; // learning factor 2 + + eoRealVectorBounds bounds; // REAL bounds even if the velocity could be of another type. + eoRealBoundModifier & bndsModifier; + + eoRng & gen; // the random generator + + // If the bound modifier doesn't need to be used, use the dummy instance + eoDummyRealBoundModifier dummyModifier; +}; + + +#endif /*EOSTANDARDVELOCITY_H */ + diff --git a/eo/src/eoStarTopology.h b/eo/src/eoStarTopology.h new file mode 100644 index 00000000..441f1f7b --- /dev/null +++ b/eo/src/eoStarTopology.h @@ -0,0 +1,136 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoStarTopology.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOSTARTOPOLOGY_H_ +#define EOSTARTOPOLOGY_H_ + +//----------------------------------------------------------------------------- +#include +#include +//----------------------------------------------------------------------------- + + +/** + * Topology dedicated to "globest best" strategy. + * All the particles of the swarm belong to the same and only social neighborhood. + * The global best is stored as a protected member and updated by using the "updateNeighborhood" method. + */ +template < class POT > class eoStarTopology:public eoTopology +{ + +public: + + /** + * The only Ctor. No parameter required. + */ + eoStarTopology ():isSetup(false){} + + + /** + * Builds the only neighborhood that contains all the particles of the given population. + * Also initializes the global best particle with the best particle of the given population. + * @param _pop - The population used to build the only neighborhood. + * @return + */ + void setup(const eoPop & _pop) + { + if (!isSetup){ + + // put all the particles in the only neighborhood + for (unsigned i=0;i < _pop.size();i++) + neighborhood.put(i); + + // set the initial global best as the best initial particle + neighborhood.best(_pop.best_element()); + + isSetup=true; + } + else + { + // Should activate this part ? + /* + std::string s; + s.append (" Linear topology already setup in eoStarTopology"); + throw std::runtime_error (s); + */ + } + } + + /* + * Update the best fitness of the given particle if it's better. + * Also replace the global best by the given particle if it's better. + * @param _po - The particle to update + * @param _indice - The indice of the given particle in the population + */ + void updateNeighborhood(POT & _po,unsigned _indice) + { + // update the best fitness of the particle + if (_po.fitness() > _po.best()) + { + _po.best(_po.fitness()); + } + // update the global best if the given particle is "better" + if (_po.fitness() > neighborhood.best().fitness()) + { + neighborhood.best(_po); + } + } + + + /** + * Return the global best particle. + * @param _indice - The indice of a particle in the population + * @return POT & - The best particle in the neighborhood of the particle whose indice is _indice + */ + POT & best (unsigned _indice) {return (neighborhood.best());} + + + /** + * Print the structure of the topology on the standard output. + * @param + * @return + */ + void printOn() + { + std::cout << "{" ; + for (unsigned i=0;i< neighborhood.size();i++) + std::cout << neighborhood.get(i) << " "; + std::cout << "}" << std::endl; + } + + +protected: + eoSocialNeighborhood neighborhood; // the only neighborhood + bool isSetup; +}; + +#endif /*EOSTARTOPOLOGY_H_ */ + + + + + + + + diff --git a/eo/src/eoSyncEasyPSO.h b/eo/src/eoSyncEasyPSO.h new file mode 100644 index 00000000..02cec6be --- /dev/null +++ b/eo/src/eoSyncEasyPSO.h @@ -0,0 +1,138 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoSyncEasyPSO.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOSYNCEASYPSO_H +#define _EOSYNCEASYPSO_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + +/** An easy-to-use synchronous particle swarm algorithm; you can use any particle, +* any flight, any topology... The main steps are : +* - perform a first evaluation of the population +* - for each generation +* - evaluate ALL the velocities +* -- perform the fligth of ALL the particles +* -- evaluate ALL the particles +* -- update the neighborhoods +*/ +template < class POT > class eoSyncEasyPSO:public eoPSO < POT > +{ +public: + + /** Full constructor + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _velocity - An eoVelocity that defines how to compute the velocities + * @param _flight - An eoFlight that defines how to make the particle flying: that means how + * to modify the positions according to the velocities + */ + eoSyncEasyPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + eoVelocity < POT > &_velocity, + eoFlight < POT > &_flight): + continuator (_continuator), + eval (_eval), + loopEval(_eval), + popEval(loopEval), + velocity (_velocity), + flight (_flight){} + + + /** Constructor without eoFlight. For special cases when the flight is performed withing the velocity. + * @param _continuator - An eoContinue that manages the stopping criterion and the checkpointing system + * @param _eval - An eoEvalFunc: the evaluation performer + * @param _velocity - An eoVelocity that defines how to compute the velocities + */ + eoSyncEasyPSO ( + eoContinue < POT > &_continuator, + eoEvalFunc < POT > &_eval, + eoVelocity < POT > &_velocity): + continuator (_continuator), + eval (_eval), + loopEval(_eval), + popEval(loopEval), + velocity (_velocity), + flight (dummyFlight){} + + + + /// Apply a few iteration of flight to the population (=swarm). + virtual void operator () (eoPop < POT > &_pop) + { + try + { + // just to use a loop eval + eoPop empty_pop; + + do + { + // perform velocity evaluation + velocity.apply (_pop); + + // apply the flight + flight.apply (_pop); + + // evaluate the position (with a loop eval, empty_swarm IS USELESS) + loopEval(empty_pop,_pop); + + // update the topology (particle and local/global best(s)) + velocity.updateNeighborhood(_pop); + + + }while (continuator (_pop)); + + } + catch (std::exception & e) + { + std::string s = e.what (); + s.append (" in eoSyncEasyPSO"); + throw std::runtime_error (s); + } + + } + +private: + eoContinue < POT > &continuator; + + eoEvalFunc < POT > &eval; + eoPopLoopEval loopEval; + eoPopEvalFunc& popEval; + + eoVelocity < POT > &velocity; + eoFlight < POT > &flight; + + // if the flight does not need to be used, use the dummy flight instance + eoDummyFlight dummyFlight; +}; + + +#endif /*_EOSYNCEASYPSO_H*/ diff --git a/eo/src/eoTimeContinue.h b/eo/src/eoTimeContinue.h new file mode 100644 index 00000000..a0f97acc --- /dev/null +++ b/eo/src/eoTimeContinue.h @@ -0,0 +1,82 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoTimeContinue.h +// (c) OPAC Team (LIFL), Dolphin Project (INRIA), 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOTIMECONTINUE_H +#define _EOTIMECONTINUE_H + +#include + +/** + * Termination condition until a running time is reached. + */ +template < class EOT > +class eoTimeContinue: public eoContinue +{ +public: + + /** + * Ctor. + * @param _max maximum running time + */ + eoTimeContinue(time_t _max): max(_max) + { + start = time(NULL); + } + + + /** + * Returns false when the running time is reached. + * @param _pop the population + */ + virtual bool operator() (const eoPop < EOT > & _pop) + { + time_t elapsed = (time_t) difftime(time(NULL), start); + if (elapsed >= max) + { + std::cout << "STOP in eoTimeContinue: Reached maximum time [" << elapsed << "/" << max << "]" << std::endl; + return false; + } + return true; + } + + + /** + * Class name + */ + virtual std::string className(void) const + { + return "eoTimeContinue"; + } + + +private: + + /** maximum running time */ + time_t max; + /** starting time */ + time_t start; + +}; + +#endif diff --git a/eo/src/eoTopology.h b/eo/src/eoTopology.h new file mode 100644 index 00000000..6a47721e --- /dev/null +++ b/eo/src/eoTopology.h @@ -0,0 +1,83 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoTopology.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOTOPOLOGY_H_ +#define EOTOPOLOGY_H_ + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + + +/** + * Define the interface for a swarm optimization topology. + */ +template < class POT > class eoTopology:public eoPop < POT > +{ +public: + + /** + * Build the neighborhoods contained in the topology. + */ + virtual void setup(const eoPop &)=0; + + /** + * Update the neighborhood of the given particle and its indice in the population + */ + virtual void updateNeighborhood(POT & ,unsigned)=0; + + + /** + * Update the neighborhood of the given particle thanks to a whole population (used for distributed or synchronous PSO) + */ + virtual void updateNeighborhood(eoPop < POT > &_pop) + { + for (unsigned i = 0; i < _pop.size (); i++) + { + updateNeighborhood(_pop[i],i); + } + } + + /** + * Build the neighborhoods contained in the topology. + */ + virtual POT & best (unsigned ) = 0; + + /** + * Build the neighborhoods contained in the topology. + * @param _pop - The population ton share between the neighborhood(s) + */ + virtual void printOn(){} +}; + + +#endif /*EOTOPOLOGY_H_ */ + + + + + + + + diff --git a/eo/src/eoVariableInertiaWeightedVelocity.h b/eo/src/eoVariableInertiaWeightedVelocity.h new file mode 100644 index 00000000..8e4c161d --- /dev/null +++ b/eo/src/eoVariableInertiaWeightedVelocity.h @@ -0,0 +1,196 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoVariableInertiaWeightedVelocity.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOVARIABLEINERTIAWEIGHTEDVELOCITY_H +#define EOVARIABLEINERTIAWEIGHTEDVELOCITY_H + +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//----------------------------------------------------------------------------- + + + +/** Inertia variable weighted based velocity performer. Derivated from abstract eoVelocity, +* At step t: v(t+1)= w*v(t) + c1*r1* ( xbest(t)-x(t) ) + c2*r2* ( gbest(t) - x(t) ) +* w is updated each time the velocity performer is called. +* (ci given and Ri chosen at random in [0;1]). +*/ +template < class POT > class eoVariableInertiaWeightedVelocity:public eoVelocity < POT > +{ + +public: + + /* + * Each element for the velocity evaluation is expected to be of type VelocityType. + */ + typedef typename POT::ParticleVelocityType VelocityType; + + /** Full constructor: Bounds and bound modifier required + * @param _topology - The topology to get the global/local/other best + * @param _weightUpdater - An eoWeightUpdater used to update the inertia weight + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _boundsModifier - An eoRealBoundModifier used to modify the bounds (for real bounds only). + * @param _gen - The eo random generator, default=rng + */ + eoVariableInertiaWeightedVelocity (eoTopology < POT > & _topology, + eoWeightUpdater & _weightUpdater, + const VelocityType & _c1, + const VelocityType & _c2 , + eoRealVectorBounds & _bounds, + eoRealBoundModifier & _bndsModifier, + eoRng & _gen = rng): + topology(_topology), + weightUpdater(_weightUpdater), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(_bndsModifier), + gen(_gen){} + + + /** Constructor: No bound updater required <-> fixed bounds + * @param _topology - The topology to get the global/local/other best + * @param _weightUpdater - An eoWeightUpdater used to update the inertia weight + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _bounds - An eoRealBaseVectorBounds: real bounds for real velocities. + * If the velocities are not real, they won't be bounded by default. Should have a eoBounds ? + * @param _gen - The eo random generator, default=rng + */ + eoVariableInertiaWeightedVelocity (eoTopology < POT > & _topology, + eoWeightUpdater & _weightUpdater, + const VelocityType & _c1, + const VelocityType & _c2, + eoRealVectorBounds & _bounds, + eoRng & _gen = rng): + topology(_topology), + weightUpdater(_weightUpdater), + c1 (_c1), + c2 (_c2), + bounds(_bounds), + bndsModifier(dummyModifier), + gen(_gen){} + + + /** Constructor: Neither bounds nor bound updater required <-> free velocity + * @param _topology - The topology to get the global/local/other best + * @param _weightUpdater - An eoWeightUpdater used to update the inertia weight + * @param _c1 - The first learning factor used for the particle's best. Type must be POT::ParticleVelocityType + * @param _c2 - The second learning factor used for the local/global best(s). Type must be POT::ParticleVelocityType + * @param _gen - The eo random generator, default=rng + */ + eoVariableInertiaWeightedVelocity (eoTopology < POT > & _topology, + eoWeightUpdater & _weightUpdater, + const VelocityType & _c1, + const VelocityType & _c2, + eoRng & _gen = rng): + topology(_topology), + weightUpdater(_weightUpdater), + c1 (_c1), + c2 (_c2), + bounds(*(new eoRealVectorNoBounds(0))), + bndsModifier(dummyModifier), + gen(_gen) + {} + + /** + * Evaluate the new velocities of the given particle. Need an indice to identify the particle + * into the topology. Steps are : + * - evaluate r1 and r2, the customed learning factors + * - adjust the size of the bounds (even if dummy) + * - update the weight with the weightUpdater (use the dummy updater if there's no updater provided) + * - modify the bounds with the bounds modifier (use the dummy modifier if there's no modifier provided) + * @param _po - A particle + * @param _indice - The indice (into the topology) of the given particle + */ + void operator () (POT & _po,unsigned _indice) + { + VelocityType r1; + VelocityType r2; + + VelocityType newVelocity; + + // cast the learning factors to VelocityType + r1 = (VelocityType) rng.uniform (1) * c1; + r2 = (VelocityType) rng.uniform (1) * c2; + + // need to resize the bounds even if there are dummy because of "isBounded" call + bounds.adjust_size(_po.size()); + + // update the inertia weight + weightUpdater(weight); + + // assign the new velocities + for (unsigned j = 0; j < _po.size (); j++) + { + newVelocity= weight * _po.velocities[j] + r1 * (_po.bestPositions[j] - _po[j]) + r2 * (topology.best (_indice)[j] - _po[j]); + + /* modify the bounds */ + bndsModifier(bounds,j); + + /* check bounds */ + if (bounds.isMinBounded(j)) + newVelocity=(VelocityType)std::max(newVelocity,bounds.minimum(j)); + if (bounds.isMaxBounded(j)) + newVelocity=(VelocityType)std::min(newVelocity,bounds.maximum(j)); + + _po.velocities[j]=newVelocity; + } + } + + /** + * Update the neighborhood. + */ + void updateNeighborhood(POT & _po,unsigned _indice) + { + topology.updateNeighborhood(_po,_indice); + } + + + +protected: + eoTopology < POT > & topology; + eoWeightUpdater & weightUpdater; // the updater used to make the weight evoluate + const VelocityType & c1; // learning factor 1 + const VelocityType & c2; // learning factor 2 + + eoRealVectorBounds & bounds; // REAL bounds even if the velocity could be of another type. + eoRealBoundModifier & bndsModifier; + + VelocityType weight; + eoRng & gen; // the random generator + + // If the bound modifier doesn't need to be used, use the dummy instance + eoDummyRealBoundModifier dummyModifier; +}; + +#endif /*EOVARIABLEINERTIAWEIGHTEDVELOCITY_H*/ + diff --git a/eo/src/eoVectorParticle.h b/eo/src/eoVectorParticle.h new file mode 100644 index 00000000..f0a123e4 --- /dev/null +++ b/eo/src/eoVectorParticle.h @@ -0,0 +1,130 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoVectorParticle.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef _EOVECTORPARTICLE_H +#define _EOVECTORPARTICLE_H + +#include + +/** + * Main class for particle representation. The positions, velocities and the best positions + * associated to the particle are stored as vectors. Inheriting from PO and std::vector, + * tree templates arguments are required: the fitness type (which is also the type of the + * particle's best fitness), the position type and the velocity type. + */ +template < class FitT, class PositionType, class VelocityType > class eoVectorParticle:public PO < FitT >, + public std::vector < + PositionType > +{ + +public: + + using PO < FitT >::invalidate; + using + std::vector < + PositionType >::operator[]; + using + std::vector < + PositionType >::begin; + using + std::vector < + PositionType >::end; + using + std::vector < + PositionType >::size; + + typedef PositionType AtomType; + typedef VelocityType ParticleVelocityType; + + + /** Default constructor. + * @param _size Length of the tree vectors (we expect the same size), default is 0 + * @param position + * @param velocity + * @param bestPositions + */ + eoVectorParticle (unsigned _size = 0,PositionType position = PositionType (), VelocityType velocity = VelocityType (), PositionType bestPositions = PositionType ()):PO < FitT > (),std::vector < PositionType > (_size, position), bestPositions (_size, bestPositions), velocities (_size, + velocity) + { + } + + + // we can't have a Ctor from a std::vector, it would create ambiguity + // with the copy Ctor + void + position (const std::vector < PositionType > &_v) + { + if (_v.size () != size ()) // safety check + { + if (size ()) // NOT an initial empty std::vector + std:: + cout << + "Warning: Changing position size in eoVectorParticle assignation" + << std::endl; + resize (_v.size ()); + } + + std::copy (_v.begin (), _v.end (), begin ()); + invalidate (); + } + + /** Resize the tree vectors of the particle: positions, velocities and bestPositions + * @param _size The new size for positions, velocities and bestPositions + */ + void + resize (unsigned _size) + { + std::vector < PositionType >::resize (_size); + bestPositions.resize (_size); + velocities.resize (_size); + } + + + /** Resize the best positions. + * @param _size The new size for the best positions. + */ + void + resizeBestPositions (unsigned _size) + { + bestPositions.resize (_size); + } + + + /** Resize the velocities. + * @param _size The new size for the velocities. + */ + void + resizeVelocities (unsigned _size) + { + velocities.resize (_size); + } + + + /* public attributes */ + std::vector < PositionType > bestPositions; + std::vector < ParticleVelocityType > velocities; + +}; + +#endif /*_EOVECTORPARTICLE_H*/ diff --git a/eo/src/eoVelocity.h b/eo/src/eoVelocity.h new file mode 100644 index 00000000..02160d95 --- /dev/null +++ b/eo/src/eoVelocity.h @@ -0,0 +1,75 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoVelocity.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOVELOCITY_H +#define EOVELOCITY_H + +//----------------------------------------------------------------------------- +#include +#include +#include +//----------------------------------------------------------------------------- + +/** + * Abstract class for PSO velocities calculation. + * All the velocities must derivated from eoVelocity. + */ +template < class POT > class eoVelocity:public eoBF < POT &,unsigned , void > +{ +public: + + /** + * Apply the velocity computation to a whole given population. + * Used for synchronous PSO. + */ + virtual void apply (eoPop < POT > &_pop) + { + for (unsigned i = 0; i < _pop.size (); i++) + { + operator ()(_pop[i],i); + } + + } + + /** + * Update the neighborhood of the given particle. + */ + virtual void updateNeighborhood(POT & ,unsigned _indice){} + + + /** + * Apply the neighborhood with a whole population (used for distributed or synchronous PSO). + */ + virtual void updateNeighborhood (eoPop < POT > &_pop) + { + for (unsigned i = 0; i < _pop.size (); i++) + { + updateNeighborhood(_pop[i],i); + } + + } +}; + +#endif /*EOVELOCITY_H_H */ + diff --git a/eo/src/eoVelocityInit.h b/eo/src/eoVelocityInit.h new file mode 100644 index 00000000..dfa931dd --- /dev/null +++ b/eo/src/eoVelocityInit.h @@ -0,0 +1,140 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoVelocityInit.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOVELOCITYINIT_H +#define EOVELOCITYINIT_H + + +#include + +#include +#include +#include + +/** Abstract class for PSO velocities initilization.*/ +template < class POT > class eoVelocityInit:public eoInit < POT > +{ +public: + virtual std::string className (void) const + { + return "eoVelocityInit"; + } +}; + + +/** +* Provide a particle initialized thanks to the eoVelocityInit object given. +*/ +template < class POT > class eoVelocityInitGenerator:public eoF < POT > +{ +public: + + /** Ctor from a plain eoVelocityInit */ + eoVelocityInitGenerator (eoVelocityInit < POT > &_init):init (_init) + { + } + + virtual POT operator () () + { + POT p; + init (p); + return (p); + } +private: + eoVelocityInit < POT > &init; +}; + +/** + Initializer for fixed length velocities with a single type +*/ +template < class POT > class eoVelocityInitFixedLength:public eoVelocityInit < + POT > +{ +public: + + typedef typename POT::ParticleVelocityType VelocityType; + + eoVelocityInitFixedLength (unsigned _combien, + eoRndGenerator < VelocityType > + &_generator):combien (_combien), + generator (_generator) + { + } + + virtual void operator () (POT & chrom) + { + chrom.resize (combien); + std::generate (chrom.velocities.begin (), chrom.velocities.end (), + generator); + } + +private: + unsigned combien; + /// generic wrapper for eoFunctor (s), to make them have the function-pointer style copy semantics + eoSTLF < VelocityType > generator; +}; + +/** + Initializer for variable length velocitys with a single type +*/ +template < class POT > class eoVelocityInitVariableLength:public eoVelocityInit < + POT > +{ +public: + typedef typename POT::ParticleVelocityType VelocityType; + + /** Ctor from an eoVelocityInit */ + eoVelocityInitVariableLength (unsigned _minSize, unsigned _maxSize, + eoVelocityInit < VelocityType > + &_init):offset (_minSize), + extent (_maxSize - _minSize), init (_init) + { + if (_minSize >= _maxSize) + throw std:: + logic_error + ("eoVelocityInitVariableLength: minSize larger or equal to maxSize"); + } + + + virtual void operator () (POT & _chrom) + { + _chrom.resizeVelocities (offset + rng.random (extent)); + typename std::vector < VelocityType >::iterator it; + for (it = _chrom.velocities.begin (); it < _chrom.velocities.end (); it++) + init (*it); + } + + // accessor to the atom initializer (needed by operator constructs sometimes) + eoInit < VelocityType > &atomInit () + { + return init; + } + +private: + unsigned offset; + unsigned extent; + eoVelocityInit < VelocityType > &init; +}; + +#endif /*EOVELOCITYINIT_H */ diff --git a/eo/src/eoWeightUpdater.h b/eo/src/eoWeightUpdater.h new file mode 100644 index 00000000..7f6cb792 --- /dev/null +++ b/eo/src/eoWeightUpdater.h @@ -0,0 +1,38 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoWeightUpdater.h +// (c) OPAC 2007 +/* + 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: thomas.legrand@lifl.fr + */ +//----------------------------------------------------------------------------- + +#ifndef EOWEIGHTUPDATER_H +#define EOWEIGHTUPDATER_H + +//----------------------------------------------------------------------------- +#include +//----------------------------------------------------------------------------- + +/** + * Abstract class for (inertia) weight updater. Used inside classes extending eoVelocity. + */ +template < class WeightType > class eoWeightUpdater: public eoUF < WeightType &, void > {}; + + +#endif/*EOWEIGHTUPDATER_H*/