evoga.h
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2012 *
4  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
5  * Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it> *
6  * Gianluca Massera <emmegian@yahoo.it> *
7  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the Free Software *
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
22  ********************************************************************************/
23 
24 #ifndef EVOGA_H
25 #define EVOGA_H
26 #include <cstdlib>
27 #include <stdio.h>
28 #include <string.h>
29 #include "evorobotexperiment.h"
30 
31 #include <configurationparameters.h>
32 #include <parametersettable.h>
33 
34 #include <QObject>
35 #include <QString>
36 #include <QMutex>
37 #include <QWaitCondition>
38 
39 namespace farsa {
40 
48 class FARSA_EXPERIMENTS_API Evoga : public QObject, public ParameterSettableWithConfigureFunction, public ConcurrentResourcesUser
49 {
50  Q_OBJECT
51 signals:
55  void startingReplication( int replication );
59  void recoveredInterruptedEvolution( QString statfile );
66  void endGeneration( int generation, int fmax, int faverage, int fmin );
68  void finished();
69 public:
71  static const int MAXINDIVIDUALS = 1000;
73  Evoga();
75  ~Evoga();
76 
78  void evolveSteadyState();
80  void evolveGenerational();
81 
82  int mrand(int i);
83  double drand(); //returns a random value between 0 and 1
84  double getNoise(double minn, double maxn); //returns noise between minn and max
85  void reproduce(); //reproduces higher individulas and advances current generation (maximization)
86  void mreproduce(); //minimize, i.e. reproduces individuals with lower ranking
87  void putGenome(int fromgenome, int tobestgenome);
88  void getGenome(int frombestgenome, int togenome, int mut); //mut=0 no mutation otherwise a mutation will be applied
89  void setSeed(int s);
90  int mutate(int w, double mut);
91  void randomizePop();
92  void setInitialPopulation(int*);
93  void setMutations(float*);
94  void printPop();
95  void printBest();
96  void saveagenotype(FILE *fp, int ind);
97  void loadgenotype(FILE *fp, int ind);
98  void saveallg(); //save all current generation
99  int loadallg(int gen, const char *filew);
100  //void saveFit();
101  void computeFStat(); //finds min, max and average fitness
102  void saveFStat();
108  void getLastFStat( double &min, double &max, double &average );
109  int loadStatistics(char *filename);
110  int* getGenes(int ind); // returns genotype data array;
111  int* getBestGenes(int ind);
112 
113  void resetGenerationCounter();
114  void copyGenes(int from, int to, int mut); //super ag copy from and to genome
115  void saveBestInd(); //super ag copy from and to genome
116  void computeFStat2(); //used by super ag
117 
123  void getPheParametersAndMutationsFromEvonet();
124 
135  virtual void configure(ConfigurationParameters& params, QString prefix);
136 
147  virtual void save(ConfigurationParameters& params, QString prefix);
148 
156  static void describe( QString type );
157 
162  virtual void postConfigureInitialization();
163 
167  virtual void evolveAllReplicas();
168 
174  void stop();
175 
201  bool commitStep();
202 
221  bool isStopped();
222 
225  void resetStop();
226 
229  bool isEnabledStepByStep();
230 
241  virtual EvoRobotExperiment* getEvoRobotExperiment();
242 
251  virtual QVector<EvoRobotExperiment*> getEvoRobotExperimentPool();
252 
258  virtual unsigned int currentGeneration();
259 
265  virtual unsigned int getStartingSeed();
266 
272  virtual unsigned int getCurrentSeed();
273 
279  virtual unsigned int getNumReplications();
280 
286  virtual unsigned int getNumOfGenerations();
287 
293  virtual double getCurrentMutationRate();
294 
299  virtual void setCurrentMutationRate( double mutation_rate );
300 
308  virtual unsigned int loadGenotypes(QString filename);
309 
315  virtual unsigned int numLoadedGenotypes() const;
316 
323  virtual int* getGenesForIndividual(unsigned int id);
324 
333  virtual QString statisticsFilename(unsigned int seed);
334 
343  virtual QString bestsFilename(unsigned int seed);
344 
348  virtual QString bestsFilename();
349 
359  virtual QString generationFilename(unsigned int generation, unsigned int seed);
360 
364  virtual QString generationFilename();
365 
370  virtual void doNotUseMultipleThreads();
371 
372 public slots:
379  void enableStepByStep( bool enable );
382  void doNextStep();
383 
384 private:
386  EvoRobotExperiment *exp;
388  int popSize;
390  int glen;
392  bool elitism;
394  int nreproducing;
396  int noffspring;
397 
402  class Population {
403  public:
404  Population() :
405  m_pop(),
406  m_genomelength(1)
407  {
408  }
409 
410  ~Population()
411  {
412  clear();
413  }
414 
415  void setGenomeLength(int genomelength)
416  {
417  if (genomelength < 1) {
418  genomelength = 1;
419  }
420  m_genomelength = genomelength;
421 
422  clear();
423  }
424 
425  int getGenomeLength() const
426  {
427  return m_genomelength;
428  }
429 
430  void resize(int newSize)
431  {
432  if (newSize < 0) {
433  newSize = 0;
434  }
435 
436  // We have to be careful clearing or allocating memory
437  if (newSize < m_pop.size()) {
438  for (int i = (m_pop.size() - 1); i >= newSize; i--) {
439  delete[] m_pop[i];
440  }
441  m_pop.resize(newSize);
442  } else if (newSize > m_pop.size()) {
443  const int oldSize = m_pop.size();
444  m_pop.resize(newSize);
445  for (int i = oldSize; i < newSize; i++) {
446  m_pop[i] = new int[m_genomelength];
447  }
448  }
449  }
450 
451  int addOne()
452  {
453  m_pop.append(new int[m_genomelength]);
454 
455  // Returning the index of the new genome
456  return (m_pop.size() - 1);
457  }
458 
459  void clear()
460  {
461  resize(0);
462  }
463 
464  int size() const
465  {
466  return m_pop.size();
467  }
468 
469  int* operator[](int i)
470  {
471 #ifdef FARSA_DEBUG
472  if (i > m_pop.size()) {
473  abort();
474  }
475 #endif
476  return m_pop[i];
477  }
478 
479  const int* operator[](int i) const
480  {
481 #ifdef FARSA_DEBUG
482  if (i > m_pop.size()) {
483  abort();
484  }
485 #endif
486  return m_pop[i];
487  }
488 
489  private:
490  QVector<int *> m_pop;
491  int m_genomelength;
492  };
494  Population genome;
496  Population bestgenome;
498  int loadedIndividuals;
499 
501  double *tfitness;
503  double **statfit;
504 
509  QString evolutionType;
511  int nogenerations;
513  int nreplications;
515  int seed;
517  int currentSeed;
519  double mutation;
521  double mutationdecay;
523  float *mutations;
525  int cgen;
527  int savebest;
529  double fmin, fmax,faverage;
531  int ccycle;
533  bool stopEvolution;
535  bool isStepByStep;
537  QMutex mutexStepByStep;
539  QWaitCondition waitForNextStep;
540 
541  //variables for the super evo algorithm
542  //double *sfit; //fitness
543  double *ntfitness; //how many times a genotype has been evalued
544 
546  unsigned int numThreads;
547 
548  int savePopulationEachNGenerations;
549 
564  bool averageIndividualFitnessOverGenerations;
565 
572  ConfigurationParameters savedConfigurationParameters;
573 
579  QString savedExperimentPrefix;
580 };
581 
582 } // end namespace farsa
583 
584 #endif