experiments/evorobot/include/evoga.h

00001 /********************************************************************************
00002  *  FARSA Experiments Library                                                   *
00003  *  Copyright (C) 2007-2012                                                     *
00004  *  Stefano Nolfi <stefano.nolfi@istc.cnr.it>                                   *
00005  *  Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it>                           *
00006  *  Gianluca Massera <emmegian@yahoo.it>                                        *
00007  *  Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it>                         *
00008  *                                                                              *
00009  *  This program is free software; you can redistribute it and/or modify        *
00010  *  it under the terms of the GNU General Public License as published by        *
00011  *  the Free Software Foundation; either version 2 of the License, or           *
00012  *  (at your option) any later version.                                         *
00013  *                                                                              *
00014  *  This program is distributed in the hope that it will be useful,             *
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
00017  *  GNU General Public License for more details.                                *
00018  *                                                                              *
00019  *  You should have received a copy of the GNU General Public License           *
00020  *  along with this program; if not, write to the Free Software                 *
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
00022  ********************************************************************************/
00023 
00024 #ifndef EVOGA_H
00025 #define EVOGA_H
00026 #include <cstdlib>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include "evorobotexperiment.h"
00030 
00031 #include <configurationparameters.h>
00032 #include <parametersettable.h>
00033 
00034 #include <QObject>
00035 #include <QString>
00036 #include <QMutex>
00037 #include <QWaitCondition>
00038 
00039 namespace farsa {
00040 
00048 class FARSA_EXPERIMENTS_API Evoga : public QObject, public ParameterSettableWithConfigureFunction, public ConcurrentResourcesUser
00049 {
00050     Q_OBJECT
00051 signals:
00055     void startingReplication( int replication );
00059     void recoveredInterruptedEvolution( QString statfile );
00066     void endGeneration( int generation, int fmax, int faverage, int fmin );
00068     void finished();
00069 public:
00071     static const int MAXINDIVIDUALS = 1000;
00073     Evoga();
00075     ~Evoga();
00076 
00078     void evolveSteadyState();
00080     void evolveGenerational();
00081 
00082     int mrand(int i);
00083     double drand();                         //returns a random value between 0 and 1
00084     double getNoise(double minn, double maxn);          //returns noise between minn and max
00085     void  reproduce();                      //reproduces higher individulas and advances current generation (maximization)
00086     void  mreproduce();                     //minimize, i.e. reproduces individuals with lower ranking
00087     void putGenome(int fromgenome, int tobestgenome);
00088     void getGenome(int frombestgenome, int togenome, int mut);  //mut=0 no mutation otherwise a mutation will be applied
00089     void setSeed(int s);
00090     int mutate(int w, double mut);
00091     void randomizePop();
00092     void setInitialPopulation(int*);
00093     void setMutations(float*);
00094     void printPop();
00095     void printBest();
00096     void saveagenotype(FILE *fp, int ind);
00097     void loadgenotype(FILE *fp, int ind);
00098     void saveallg();                        //save all current generation
00099     int loadallg(int gen, const char *filew);
00100     //void saveFit();
00101     void computeFStat();                        //finds min, max and average fitness
00102     void saveFStat();
00108     void getLastFStat( double &min, double &max, double &average );
00109     int loadStatistics(char *filename);
00110     int* getGenes(int ind);                     // returns genotype data array;
00111     int* getBestGenes(int ind);
00112 
00113     void resetGenerationCounter();
00114     void copyGenes(int from, int to, int mut);          //super ag copy from and to genome
00115     void saveBestInd();                     //super ag copy from and to genome
00116     void computeFStat2();                       //used by super ag
00117 
00123     void getPheParametersAndMutationsFromEvonet();
00124 
00135     virtual void configure(ConfigurationParameters& params, QString prefix);
00136 
00147     virtual void save(ConfigurationParameters& params, QString prefix);
00148     
00156     static void describe( QString type );
00157     
00162     virtual void postConfigureInitialization();
00163 
00167     virtual void evolveAllReplicas();
00168     
00174     void stop();
00175     
00201     bool commitStep();
00202 
00221     bool isStopped();
00222     
00225     void resetStop();
00226     
00229     bool isEnabledStepByStep();
00230 
00241     virtual EvoRobotExperiment* getEvoRobotExperiment();
00242 
00251     virtual QVector<EvoRobotExperiment*> getEvoRobotExperimentPool();
00252 
00258     virtual unsigned int currentGeneration();
00259 
00265     virtual unsigned int getStartingSeed();
00266 
00272     virtual unsigned int getCurrentSeed();
00273 
00279     virtual unsigned int getNumReplications();
00280     
00286     virtual unsigned int getNumOfGenerations();
00287     
00293     virtual double getCurrentMutationRate();
00294 
00299     virtual void setCurrentMutationRate( double mutation_rate );
00300 
00308     virtual unsigned int loadGenotypes(QString filename);
00309 
00315     virtual unsigned int numLoadedGenotypes() const;
00316     
00323     virtual int* getGenesForIndividual(unsigned int id);
00324 
00333     virtual QString statisticsFilename(unsigned int seed);
00334 
00343     virtual QString bestsFilename(unsigned int seed);
00344 
00348     virtual QString bestsFilename();
00349 
00359     virtual QString generationFilename(unsigned int generation, unsigned int seed);
00360     
00364     virtual QString generationFilename();
00365     
00370     virtual void doNotUseMultipleThreads();
00371 
00372 public slots:
00379     void enableStepByStep( bool enable );
00382     void doNextStep();
00383 
00384 private:
00386     EvoRobotExperiment *exp;
00388     int popSize;
00390     int glen;
00392     bool elitism;
00394     int nreproducing;
00396     int noffspring;
00397 
00402     class Population {
00403     public:
00404         Population() :
00405             m_pop(),
00406             m_genomelength(1)
00407         {
00408         }
00409 
00410         ~Population()
00411         {
00412             clear();
00413         }
00414 
00415         void setGenomeLength(int genomelength)
00416         {
00417             if (genomelength < 1) {
00418                 genomelength = 1;
00419             }
00420             m_genomelength = genomelength;
00421 
00422             clear();
00423         }
00424 
00425         int getGenomeLength() const
00426         {
00427             return m_genomelength;
00428         }
00429 
00430         void resize(int newSize)
00431         {
00432             if (newSize < 0) {
00433                 newSize = 0;
00434             }
00435 
00436             // We have to be careful clearing or allocating memory
00437             if (newSize < m_pop.size()) {
00438                 for (int i = (m_pop.size() - 1); i >= newSize; i--) {
00439                     delete[] m_pop[i];
00440                 }
00441                 m_pop.resize(newSize);
00442             } else if (newSize > m_pop.size()) {
00443                 const int oldSize = m_pop.size();
00444                 m_pop.resize(newSize);
00445                 for (int i = oldSize; i < newSize; i++) {
00446                     m_pop[i] = new int[m_genomelength];
00447                 }
00448             }
00449         }
00450 
00451         int addOne()
00452         {
00453             m_pop.append(new int[m_genomelength]);
00454 
00455             // Returning the index of the new genome
00456             return (m_pop.size() - 1);
00457         }
00458 
00459         void clear()
00460         {
00461             resize(0);
00462         }
00463 
00464         int size() const
00465         {
00466             return m_pop.size();
00467         }
00468 
00469         int* operator[](int i)
00470         {
00471 #ifdef FARSA_DEBUG
00472             if (i > m_pop.size()) {
00473                 abort();
00474             }
00475 #endif
00476             return m_pop[i];
00477         }
00478 
00479         const int* operator[](int i) const
00480         {
00481 #ifdef FARSA_DEBUG
00482             if (i > m_pop.size()) {
00483                 abort();
00484             }
00485 #endif
00486             return m_pop[i];
00487         }
00488 
00489     private:
00490         QVector<int *> m_pop;
00491         int m_genomelength;
00492     };
00494     Population genome;
00496     Population bestgenome;
00498     int loadedIndividuals;
00499 
00501     double *tfitness;
00503     double **statfit;
00504 
00509     QString evolutionType;
00511     int nogenerations;
00513     int nreplications;
00515     int seed;
00517     int currentSeed;
00519     double mutation;
00521     double mutationdecay;
00523     float *mutations;
00525     int cgen;
00527     int savebest;
00529     double fmin, fmax,faverage;
00531     int ccycle;
00533     bool stopEvolution;
00535     bool isStepByStep;
00537     QMutex mutexStepByStep;
00539     QWaitCondition waitForNextStep;
00540 
00541     //variables for the super evo algorithm
00542     //double *sfit;  //fitness
00543     double *ntfitness;      //how many times a genotype has been evalued
00544 
00546     unsigned int numThreads;
00547 
00548     int savePopulationEachNGenerations;
00549 
00564     bool averageIndividualFitnessOverGenerations;
00565 
00572     ConfigurationParameters savedConfigurationParameters;
00573 
00579     QString savedExperimentPrefix;
00580 };
00581 
00582 } // end namespace farsa
00583 
00584 #endif