// "peoAsyncIslandMig.h" // (c) OPAC Team, LIFL, August 2005 /* Contact: paradiseo-help@lists.gforge.inria.fr */ #ifndef __peoAsyncIslandMig_h #define __peoAsyncIslandMig_h #include #include #include #include #include #include #include "core/topology.h" #include "core/cooperative.h" #include "core/eoPop_comm.h" #include "core/peo_debug.h" //! Class providing the basis for the asynchronous island migration model. //! The peoAsyncIslandMig class offers the elementary basis for implementating an //! asynchronous island migration model - requires the specification of several basic //! parameters, i.e. continuation criterion, selection and replacement strategies, //! a topological model and the source and destination population for the migrating individuals. //! As opposed to the synchronous migration model, in the asynchronous migration approach, there is //! no synchronization step between islands after performing the emigration phase. //! //! The migration operator is called at the end of each generation of an evolutionary algorithms //! as a checkpoint object - the following code exposes the structure of a classic evolutionary algorithm: //! //! //! //! //! //! //! //! //!
do {    
         select( population, offsprings );   // select the offsprings from the current population
         transform( offsprings );   // crossover and mutation operators are applied on the selected offsprings
         evaluate( offsprings );   // evaluation step of the resulting offsprings
         replace( population, offsprings );   // replace the individuals in the current population whith individuals from the offspring population, according to a specified replacement strategy
} while ( eaCheckpointContinue( population ) );   // checkpoint operators are applied on the current population, including the migration operator, if any specified
//! //! Constructing an asynchronous island migration model requires having defined (1) a topological migration model, //! (2) the control parameters of the migration process, (3) a checkpoint object associated with an evolutionary algorithm, //! and (4) an owner object must be set. The owner object must be derived from the Runner class (for example //! a peoEA object represents a possible owner). //! A simple example is offered bellow: //! //!
    //!
  1. topological model to be followed when performing migrations:
    //!
    //! //! //!
    RingTopology migTopology;   // a simple ring topological model - each island communicates with two other islands
    //!
  2. //! //!
  3. the continuation criterion, selection and replacement strategy etc. are defined:
    //!
    //! //! //! //! //! //! //! //! //! //! //!
    eoPop< EOT > population( POP_SIZE, popInitializer );   // population of individuals to be used for the evolutionary algorithm
       
    eoPeriodicContinue< EOT > migCont( MIG_FREQ );   // migrations occur periodically at MIG_FREQ iterations
    eoRandomSelect< EOT > migSelectStrategy;   // selection strategy - in this case a random selection is applied
    eoSelectNumber< EOT > migSelect( migSelectStrategy, MIG_SIZE );   // number of individuals to be selected using the specified strategy
    eoPlusReplacement< EOT > migReplace;   // immigration strategy - the worse individuals in the destination population are replaced by the immigrant individuals
       
    peoAsyncIslandMig< EOT > asyncMigration( //!
             migCont, migSelect, migReplace, migTopology, //!
             population, population //!
    );  
    // asynchronous migration object - the emigrant individuals are selected from the same from population in which the immigrant individuals are being integrated
    //!
  4. //! //!
  5. creation of a checkpoint object as part of the definition of an evolutionary algoritm (details of th EA not given as being out of scope):
    //!
    //! //! //! //! //! //! //! //!
    ...    
    eoGenContinue< EOT > eaCont( NUM_GEN );   // the evolutionary algorithm will stop after NUM_GEN generations
    eoCheckPoint< EOT > eaCheckpointContinue( eaCont );   // number of individuals to be selected using the specified strategy
    ...    
    eaCheckpointContinue.add( asyncMigration );   // adding the migration operator as checkpoint element
    ...    
    //!
  6. //! //!
  7. definition of an owner evolutionary algorithm (an object inheriting the Runner class):
    //!
    //! //! //! //! //!
    peoEA< EOT > eaAlg( eaCheckpointContinue, eaPopEval, eaSelect, eaTransform, eaReplace);   // evolutionary algorithm having as checkpoint the eaCheckpointContinue object defined above
    asyncMigration.setOwner( eaAlg );   // setting the evolutionary algorithm as owner of the migration object
    eaAlg( population );   // applying the evolutionary algorithm on a given population
    //!
  8. //!
//! //! The source and the destination population for the migration object were specified as being the same, in step no. 2, //! as we are usually interested in selecting the emigrants and integrating the immigrant individuals from and in, respectively, one unique //! population, iteratively evolved by an evolutionary algorithm. There is no restriction in having two distinct populations //! as source and destination for the emigrant and immigrant individuals respectively. //! //! The above steps only create an asynchronous migration object associated to an evolutionary algorithm. The creation of several //! islands requires the reiteration of the steps 2 through 4 for creating distinct algorithms, with distinct populations and //! the associated distinctly parametrized migration objects. The interconnecting element is the underlying topology, defined at step 1 //! (the same C++ migTopology object has to be passed as parameter for all the migration objects, in order to interconnect them). template< class EOT > class peoAsyncIslandMig : public Cooperative, public eoUpdater { public: //! Constructor for the peoAsyncIslandMig class; the characteristics of the migration model are defined //! through the specified parameters - out of the box objects provided in EO, etc., or custom, derived objects may be passed as parameters. //! //! @param eoContinue< EOT >& __cont - continuation criterion specifying whether the migration is performed or not; //! @param eoSelect< EOT >& __select - selection strategy to be applied for constructing a list of emigrant individuals out of the source population; //! @param eoReplacement< EOT >& __replace - replacement strategy used for integrating the immigrant individuals in the destination population; //! @param Topology& __topology - topological model to be followed when performing migrations; //! @param eoPop< EOT >& __source - source population from which the emigrant individuals are selected; //! @param eoPop< EOT >& __destination - destination population in which the immigrant population are integrated. peoAsyncIslandMig( eoContinue< EOT >& __cont, eoSelect< EOT >& __select, eoReplacement< EOT >& __replace, Topology& __topology, eoPop< EOT >& __source, eoPop< EOT >& __destination ); //! Function operator to be called as checkpoint for performing the migration step. The emigrant individuals are selected //! from the source population and sent to the next island (defined by the topology object) while the immigrant //! individuals are integrated in the destination population. There is no need to explicitly call the function - the //! wrapper checkpoint object (please refer to the above example) will perform the call when required. void operator()(); //! Auxiliary function dealing with sending the emigrant individuals. There is no need to explicitly call the function. void pack(); //! Auxiliary function dealing with receiving immigrant individuals. There is no need to explicitly call the function. void unpack(); private: void emigrate(); void immigrate(); private: eoContinue< EOT >& cont; // continuator eoSelect< EOT >& select; // the selection strategy eoReplacement< EOT >& replace; // the replacement strategy Topology& topology; // the neighboring topology // source and destination populations eoPop< EOT >& source; eoPop< EOT >& destination; // immigrants & emigrants in the queue std :: queue< eoPop< EOT > > imm; std :: queue< eoPop< EOT > > em; std :: queue< Cooperative* > coop_em; }; template< class EOT > peoAsyncIslandMig< EOT > :: peoAsyncIslandMig( eoContinue< EOT >& __cont, eoSelect< EOT >& __select, eoReplacement< EOT >& __replace, Topology& __topology, eoPop< EOT >& __source, eoPop< EOT >& __destination ) : cont( __cont ), select( __select ), replace( __replace ), topology( __topology ), source( __source ), destination( __destination ) { __topology.add( *this ); } template< class EOT > void peoAsyncIslandMig< EOT > :: pack() { lock(); { :: pack( coop_em.front()->getKey() ); :: pack( em.front() ); coop_em.pop(); em.pop(); } unlock(); } template< class EOT > void peoAsyncIslandMig< EOT > :: unpack() { lock(); { eoPop< EOT > mig; :: unpack( mig ); imm.push( mig ); } unlock(); } template< class EOT > void peoAsyncIslandMig< EOT > :: emigrate() { std :: vector< Cooperative* >in, out; topology.setNeighbors( this, in, out ); for ( unsigned i = 0; i < out.size(); i++ ) { eoPop< EOT > mig; select( source, mig ); em.push( mig ); coop_em.push( out[i] ); send( out[i] ); printDebugMessage( "sending some emigrants." ); } } template< class EOT > void peoAsyncIslandMig< EOT > :: immigrate() { lock(); { while ( !imm.empty() ) { replace( destination, imm.front() ); imm.pop(); printDebugMessage( "receiving some immigrants." ); } } unlock(); } template< class EOT > void peoAsyncIslandMig< EOT > :: operator()() { if ( !cont( source ) ) { emigrate(); // sending emigrants immigrate(); // receiving immigrants } } #endif