ARGoS Example

mpga.h

<- back

#ifndef MPGA_H
#define MPGA_H
 
#include <vector>
#include <argos3/core/utility/datatypes/datatypes.h>
#include <argos3/core/utility/math/range.h>
#include <argos3/core/utility/math/rng.h>
 
using namespace argos;
 
/*
 * A simple multi-process genetic algorithm that launches multiple
 * instances of ARGoS in several parallel processes.
 *
 * The program is structured into a master process and a number of
 * slave processes. The master process manages initialization,
 * selection, crossover, and mutation; the slave processes are used to
 * perform the trials.
 *
 * The slave processes load ARGoS once, and then keep resetting the
 * simulation to prepare each trial. The .argos file contains only the
 * parts that do not change over the trials; the loop functions manage
 * the rest.
 *
 * Communication between master and slaves occurs in two ways:
 * - signals are sent to suspend and resume processes;
 * - a memory-mapped, shared memory file is used for data exchange.
 *
 * The benefit of this solution is that the optimization proceeds in a
 * parallel fashion, without the need to destroy and reload ARGoS for
 * every trial.
 *
 * To use this class, your loop functions must inherit from
 * CMPGALoopFunctions.
 */
class CMPGA {
 
public:
 
   /**
    * Information about an individual.
    */
   struct SIndividual {
      std::vector<Real> Genome;
      Real Score;
   };
 
   /** A population is a list of parameter sets */
   typedef std::vector<SIndividual*> TPopulation;
 
   /** Score aggregator function pointer */
   typedef Real (*TScoreAggregator)(const std::vector<Real>&);
 
public:
 
   /**
    * Class constructor.
    * @param c_allele_range The range of each allele of the genome.
    * @param un_genome_size The size of the genome of an individual.
    * @param un_pop_size The size of the population.
    * @param f_mutation_prob The mutation probability.
    * @param un_num_trials The number of trials per individual.
    * @param un_generations The max number of generations.
    * @param b_maximize true to maximize, false to minimize.
    * @param str_argosconf Path of the .argos file to use.
    * @param t_score_aggregator The function used to aggregate the trial scores.
    * @param un_random_seed The random seed.
    */
   CMPGA(const CRange<Real>& c_allele_range,
         UInt32 un_genome_size,
         UInt32 un_pop_size,
         Real f_mutation_prob,
         UInt32 un_num_trials,
         UInt32 un_generations,
         bool b_maximize,
         const std::string& str_argosconf,
         TScoreAggregator t_score_aggregator,
         UInt32 un_random_seed);
 
   /**
    * Class destructor.
    */
   ~CMPGA();
 
   /**
    * Returns the current population.
    */
   const TPopulation& GetPopulation() const;
 
   /**
    * Returns the current generation.
    */
   UInt32 GetGeneration() const;
 
   /**
    * Tidies up memory and close files.
    * Used internally, don't call it from user code.
    */
   virtual void Cleanup();
 
   /**
    * Runs the trials to evaluate the current population.
    */
   virtual void Evaluate();
 
   /**
    * Executes the next generation.
    */
   virtual void NextGen();
 
   /**
    * Returns true if the evolution is finished, false otherwise.
    */
   virtual bool Done() const;
 
private:
 
   /** Executes the slave process that manages ARGoS */
   virtual void LaunchARGoS(UInt32 un_slave_id);
 
   /**
    * Discards all the individuals apart from the top two.
    */
   virtual void Selection();
 
   /**
    * Performs crossover among the best individuals.
    */
   virtual void Crossover();
 
   /**
    * Performs mutation 
    */
   virtual void Mutation();
 
private:
 
   /** Shared memory manager for data exchange between master and slaves */
   class CSharedMem {
 
   public:
 
      /**
       * Class constructor.
       * @param un_genome_size The size of the genome of an individual.
       * @param un_pop_size The size of the population.
       */
      CSharedMem(UInt32 un_genome_size,
                 UInt32 un_pop_size);
 
      /**
       * Class destructor.
       */
      ~CSharedMem();
 
      /**
       * Returns the genome of an individual.
       * @param un_individual The individual.
       */
      Real* GetGenome(UInt32 un_individual);
 
      /**
       * Sets the genome of an individual.
       * @param un_individual The individual.
       * @param pf_genome The genome.
       */
      void SetGenome(UInt32 un_individual,
                     const Real* pf_genome);
 
      /**
       * Returns the score of an individual.
       * @param un_individual The individual.
       */
      Real GetScore(UInt32 un_individual);
 
      /**
       * Sets the score of an individual.
       * @param un_individual The individual.
       * @param f_score The score.
       */
      void SetScore(UInt32 un_individual,
                    Real f_score);
 
   private:
 
      /** Genome size */
      UInt32 m_unGenomeSize;
 
      /** Population size */
      UInt32 m_unPopSize;
 
      /** File descriptor for shared memory area */
      int m_nSharedMemFD;
 
      /** Pointer to the shared memory area */
      Real* m_pfSharedMem;
 
   };
 
protected:
 
   /** Current population */
   TPopulation m_tPopulation;
 
   /** Current generation */
   UInt32 m_unCurrentGeneration;
 
   /** The range of each allele in the genome */
   CRange<Real> m_cAlleleRange;
 
   /** Genome size */
   UInt32 m_unGenomeSize;
 
   /** Population size */
   UInt32 m_unPopSize;
 
   /** Mutation probability */
   Real m_fMutationProb;
 
   /** Number of trials per individual */
   UInt32 m_unNumTrials;
 
   /** Number of generations */
   UInt32 m_unGenerations;
 
   /** Path to the .argos file to use */
   std::string m_strARGoSConf;
 
   /** The function used to aggregate the scores */
   TScoreAggregator m_tScoreAggregator;
 
   /** PID of the master process */
   pid_t MasterPID;
 
   /** PIDs of the slave processes */
   std::vector<pid_t> SlavePIDs;
 
   /** The shared memory manager */
   CSharedMem* m_pcSharedMem;
 
   /** Random number generator */
   CRandom::CRNG* m_pcRNG;
 
   /** Comparison function to sort the population */
   bool (*m_cIndComparator)(const SIndividual*,
                            const SIndividual*);
};
 
#endif
 

<- back