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 
91  void evolveSteadyState();
99  void evolveGenerational();
104  int mrand(int i);
109  double drand();
112  double getNoise(double minn, double maxn);
116  void reproduce();
122  void mreproduce();
128  void putGenome(int fromgenome, int tobestgenome);
136  void getGenome(int frombestgenome, int togenome, int mut);
141  void setSeed(int s);
149  int mutate(int w, double mut);
153  void randomizePop();
161  void setInitialPopulation(int*);
166  void setMutations(float*);
169  void printPop();
172  void printBest();
178  void saveagenotype(FILE *fp, int ind);
184  void loadgenotype(FILE *fp, int ind);
188  void saveallg();
194  int loadallg(int gen, const char *filew);
198  void computeFStat();
202  void computeFStat2();
206  void saveFStat();
212  void getLastFStat( double &min, double &max, double &average );
218  int loadStatistics(char *filename);
223  int* getGenes(int ind);
228  int* getBestGenes(int ind);
231  void resetGenerationCounter();
242  void copyGenes(int from, int to, int mut);
245  void saveBestInd();
251  void getPheParametersAndMutationsFromEvonet();
252 
256  void updateGenomeFromEvonet( int ind );
257 
268  virtual void configure(ConfigurationParameters& params, QString prefix);
269 
280  virtual void save(ConfigurationParameters& params, QString prefix);
281 
289  static void describe( QString type );
290 
295  virtual void postConfigureInitialization();
296 
300  virtual void evolveAllReplicas();
301 
307  void stop();
308 
334  bool commitStep();
335 
354  bool isStopped();
355 
358  void resetStop();
359 
362  bool isEnabledStepByStep();
363 
374  virtual EvoRobotExperiment* getEvoRobotExperiment();
375 
384  virtual QVector<EvoRobotExperiment*> getEvoRobotExperimentPool();
385 
391  virtual unsigned int currentGeneration();
392 
398  virtual unsigned int getStartingSeed();
399 
405  virtual unsigned int getCurrentSeed();
406 
412  virtual unsigned int getNumReplications();
413 
419  virtual unsigned int getNumOfGenerations();
420 
426  virtual double getCurrentMutationRate();
427 
432  virtual void setCurrentMutationRate( double mutation_rate );
433 
441  virtual unsigned int loadGenotypes(QString filename);
442 
448  virtual unsigned int numLoadedGenotypes() const;
449 
456  virtual int* getGenesForIndividual(unsigned int id);
457 
466  virtual QString statisticsFilename(unsigned int seed);
467 
476  virtual QString bestsFilename(unsigned int seed);
477 
481  virtual QString bestsFilename();
482 
492  virtual QString generationFilename(unsigned int generation, unsigned int seed);
493 
497  virtual QString generationFilename();
498 
503  virtual void doNotUseMultipleThreads();
504 
505 public slots:
512  void enableStepByStep( bool enable );
515  void doNextStep();
516 
517 private:
519  EvoRobotExperiment *exp;
521  int popSize;
523  int glen;
525  bool elitism;
527  int nreproducing;
529  int noffspring;
530 
535  class Population {
536  public:
537  Population() :
538  m_pop(),
539  m_genomelength(1)
540  {
541  }
542 
543  ~Population()
544  {
545  clear();
546  }
547 
548  void setGenomeLength(int genomelength)
549  {
550  if (genomelength < 1) {
551  genomelength = 1;
552  }
553  m_genomelength = genomelength;
554 
555  clear();
556  }
557 
558  int getGenomeLength() const
559  {
560  return m_genomelength;
561  }
562 
563  void resize(int newSize)
564  {
565  if (newSize < 0) {
566  newSize = 0;
567  }
568 
569  // We have to be careful clearing or allocating memory
570  if (newSize < m_pop.size()) {
571  for (int i = (m_pop.size() - 1); i >= newSize; i--) {
572  delete[] m_pop[i];
573  }
574  m_pop.resize(newSize);
575  } else if (newSize > m_pop.size()) {
576  const int oldSize = m_pop.size();
577  m_pop.resize(newSize);
578  for (int i = oldSize; i < newSize; i++) {
579  m_pop[i] = new int[m_genomelength];
580  }
581  }
582  }
583 
584  int addOne()
585  {
586  m_pop.append(new int[m_genomelength]);
587 
588  // Returning the index of the new genome
589  return (m_pop.size() - 1);
590  }
591 
592  void clear()
593  {
594  resize(0);
595  }
596 
597  int size() const
598  {
599  return m_pop.size();
600  }
601 
602  int* operator[](int i)
603  {
604 #ifdef FARSA_DEBUG
605  if (i > m_pop.size()) {
606  abort();
607  }
608 #endif
609  return m_pop[i];
610  }
611 
612  const int* operator[](int i) const
613  {
614 #ifdef FARSA_DEBUG
615  if (i > m_pop.size()) {
616  abort();
617  }
618 #endif
619  return m_pop[i];
620  }
621 
622  private:
623  QVector<int *> m_pop;
624  int m_genomelength;
625  };
627  Population genome;
629  Population bestgenome;
631  int loadedIndividuals;
633  double *tfitness;
635  double *ntfitness;
637  double **statfit;
642  QString evolutionType;
644  int nogenerations;
646  int nreplications;
648  int seed;
650  int currentSeed;
652  double mutation;
656  double mutationdecay;
658  double initial_mutation;
660  float *mutations;
662  int cgen;
664  int savebest;
666  double fmin, fmax,faverage;
668  int ccycle;
670  bool stopEvolution;
672  bool isStepByStep;
674  QMutex mutexStepByStep;
676  QWaitCondition waitForNextStep;
678  unsigned int numThreads;
680  int savePopulationEachNGenerations;
695  bool averageIndividualFitnessOverGenerations;
696 
703  ConfigurationParameters savedConfigurationParameters;
704 
710  QString savedExperimentPrefix;
711 };
712 
713 } // end namespace farsa
714 
715 #endif