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, double fmax, double faverage, double 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 
128  void updateGenomeFromEvonet( int ind );
129 
140  virtual void configure(ConfigurationParameters& params, QString prefix);
141 
152  virtual void save(ConfigurationParameters& params, QString prefix);
153 
161  static void describe( QString type );
162 
167  virtual void postConfigureInitialization();
168 
172  virtual void evolveAllReplicas();
173 
179  void stop();
180 
206  bool commitStep();
207 
226  bool isStopped();
227 
230  void resetStop();
231 
234  bool isEnabledStepByStep();
235 
246  virtual EvoRobotExperiment* getEvoRobotExperiment();
247 
256  virtual QVector<EvoRobotExperiment*> getEvoRobotExperimentPool();
257 
263  virtual unsigned int currentGeneration();
264 
270  virtual unsigned int getStartingSeed();
271 
277  virtual unsigned int getCurrentSeed();
278 
284  virtual unsigned int getNumReplications();
285 
291  virtual unsigned int getNumOfGenerations();
292 
298  virtual double getCurrentMutationRate();
299 
304  virtual void setCurrentMutationRate( double mutation_rate );
305 
313  virtual unsigned int loadGenotypes(QString filename);
314 
320  virtual unsigned int numLoadedGenotypes() const;
321 
328  virtual int* getGenesForIndividual(unsigned int id);
329 
338  virtual QString statisticsFilename(unsigned int seed);
339 
348  virtual QString bestsFilename(unsigned int seed);
349 
353  virtual QString bestsFilename();
354 
364  virtual QString generationFilename(unsigned int generation, unsigned int seed);
365 
369  virtual QString generationFilename();
370 
375  virtual void doNotUseMultipleThreads();
376 
377 public slots:
384  void enableStepByStep( bool enable );
387  void doNextStep();
388 
389 private:
391  EvoRobotExperiment *exp;
393  int popSize;
395  int glen;
397  bool elitism;
399  int nreproducing;
401  int noffspring;
402 
407  class Population {
408  public:
409  Population() :
410  m_pop(),
411  m_genomelength(1)
412  {
413  }
414 
415  ~Population()
416  {
417  clear();
418  }
419 
420  void setGenomeLength(int genomelength)
421  {
422  if (genomelength < 1) {
423  genomelength = 1;
424  }
425  m_genomelength = genomelength;
426 
427  clear();
428  }
429 
430  int getGenomeLength() const
431  {
432  return m_genomelength;
433  }
434 
435  void resize(int newSize)
436  {
437  if (newSize < 0) {
438  newSize = 0;
439  }
440 
441  // We have to be careful clearing or allocating memory
442  if (newSize < m_pop.size()) {
443  for (int i = (m_pop.size() - 1); i >= newSize; i--) {
444  delete[] m_pop[i];
445  }
446  m_pop.resize(newSize);
447  } else if (newSize > m_pop.size()) {
448  const int oldSize = m_pop.size();
449  m_pop.resize(newSize);
450  for (int i = oldSize; i < newSize; i++) {
451  m_pop[i] = new int[m_genomelength];
452  }
453  }
454  }
455 
456  int addOne()
457  {
458  m_pop.append(new int[m_genomelength]);
459 
460  // Returning the index of the new genome
461  return (m_pop.size() - 1);
462  }
463 
464  void clear()
465  {
466  resize(0);
467  }
468 
469  int size() const
470  {
471  return m_pop.size();
472  }
473 
474  int* operator[](int i)
475  {
476 #ifdef FARSA_DEBUG
477  if (i > m_pop.size()) {
478  abort();
479  }
480 #endif
481  return m_pop[i];
482  }
483 
484  const int* operator[](int i) const
485  {
486 #ifdef FARSA_DEBUG
487  if (i > m_pop.size()) {
488  abort();
489  }
490 #endif
491  return m_pop[i];
492  }
493 
494  private:
495  QVector<int *> m_pop;
496  int m_genomelength;
497  };
499  Population genome;
501  Population bestgenome;
503  int loadedIndividuals;
504 
506  double *tfitness;
508  double **statfit;
509 
514  QString evolutionType;
516  int nogenerations;
518  int nreplications;
520  int seed;
522  int currentSeed;
524  double mutation;
526  double mutationdecay;
528  double initial_mutation;
530  float *mutations;
532  int cgen;
534  int savebest;
536  double fmin, fmax,faverage;
538  int ccycle;
540  bool stopEvolution;
542  bool isStepByStep;
544  QMutex mutexStepByStep;
546  QWaitCondition waitForNextStep;
547 
548  //variables for the super evo algorithm
549  //double *sfit; //fitness
550  double *ntfitness; //how many times a genotype has been evalued
551 
553  unsigned int numThreads;
554 
555  int savePopulationEachNGenerations;
556 
571  bool averageIndividualFitnessOverGenerations;
572 
579  ConfigurationParameters savedConfigurationParameters;
580 
586  QString savedExperimentPrefix;
587 };
588 
589 } // end namespace farsa
590 
591 #endif