CEvolutionaryAlgorithm.cpp 23.1 KB
Newer Older
1 2 3
//#ifdef WIN32
//#pragma comment(lib, "WinMM.lib")
//#endif
kruger's avatar
kruger committed
4 5 6 7 8 9 10 11 12 13 14 15
/*
 * CEvolutionaryAlgorithm.cpp
 *
 *  Created on: 22 juin 2009
 *      Author: maitre
 */

#include "include/CEvolutionaryAlgorithm.h"
#ifndef WIN32
#include <sys/time.h>
#endif
#ifdef WIN32
16
#define WIN32_LEAN_AND_MEAN
kruger's avatar
kruger committed
17
#include <windows.h>
18
#include <mmsystem.h>
19
#endif
20 21

#include <stdio.h>
22
#include <time.h>
kruger's avatar
kruger committed
23
#include <math.h>
kruger's avatar
kruger committed
24
#include <string.h>
kruger's avatar
kruger committed
25 26
#include "include/CIndividual.h"
#include "include/Parameters.h"
Frédéric Krüger's avatar
Frédéric Krüger committed
27
#include "include/CGrapher.h"
kruger's avatar
kruger committed
28
#include "include/global.h"
kruger's avatar
kruger committed
29 30
#include "include/CComUDPLayer.h"
#include "include/CRandomGenerator.h"
kruger's avatar
kruger committed
31
#include <stdio.h>
kruger's avatar
kruger committed
32 33
#include <sstream>
#include <fstream>
kruger's avatar
kruger committed
34

Ogier Maitre's avatar
Ogier Maitre committed
35 36 37 38 39 40 41 42 43 44
//#define INSTRUMENTED
#ifdef INSTRUMENTED
#define TIMING
#include <timing.h>
#else
#define TIME_ST(f)
#define TIME_END(f)
#define TIME_ACC(f)
#endif

maitre's avatar
maitre committed
45 46
using namespace std;

kruger's avatar
kruger committed
47
extern CRandomGenerator* globalRandomGenerator;
48
extern CEvolutionaryAlgorithm* EA;
kruger's avatar
kruger committed
49 50
void EASEABeginningGenerationFunction(CEvolutionaryAlgorithm* evolutionaryAlgorithm);
void EASEAEndGenerationFunction(CEvolutionaryAlgorithm* evolutionaryAlgorithm);
maitre's avatar
maitre committed
51
void EASEAGenerationFunctionBeforeReplacement(CEvolutionaryAlgorithm* evolutionaryAlgorithm);
52 53 54

extern void evale_pop_chunk(CIndividual** pop, int popSize);
extern bool INSTEAD_EVAL_STEP;
kruger's avatar
kruger committed
55

kruger's avatar
kruger committed
56 57 58
/**
 * @DEPRECATED the next contructor has to be used instead of this one.
 */
Ogier Maitre's avatar
Ogier Maitre committed
59 60
/*CEvolutionaryAlgorithm::CEvolutionaryAlgorithm( unsigned parentPopulationSize,
					      unsigned offspringPopulationSize,
kruger's avatar
kruger committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
					      float selectionPressure, float replacementPressure, float parentReductionPressure, float offspringReductionPressure,
					      CSelectionOperator* selectionOperator, CSelectionOperator* replacementOperator,
					      CSelectionOperator* parentReductionOperator, CSelectionOperator* offspringReductionOperator,
					      float pCrossover, float pMutation,
					      float pMutationPerGene){

  CRandomGenerator* rg = globalRandomGenerator;

  CSelectionOperator* so = selectionOperator;
  CSelectionOperator* ro = replacementOperator;

  //CIndividual::initRandomGenerator(rg);
  CPopulation::initPopulation(so,ro,parentReductionOperator,offspringReductionOperator,selectionPressure,replacementPressure,parentReductionPressure,offspringReductionPressure);

  this->population = new CPopulation(parentPopulationSize,offspringPopulationSize,
				    pCrossover,pMutation,pMutationPerGene,rg,NULL);

  this->currentGeneration = 0;

  this->reduceParents = 0;
  this->reduceOffsprings = 0;
maitre's avatar
maitre committed
82
  
kruger's avatar
kruger committed
83 84 85 86 87
  // INITIALIZE SERVER OBJECT ISLAND MODEL
  if(params->remoteIslandModel){
  	this->server = new CComUDPServer(2909,0);
	this->treatedIndividuals = 0;
	this->numberOfClients = 0;
kruger's avatar
kruger committed
88

kruger's avatar
kruger committed
89 90 91 92 93 94 95
	this->initializeClients();
  }
}*/

/*****
 * REAL CONSTRUCTOR
 */
kruger's avatar
kruger committed
96 97
CEvolutionaryAlgorithm::CEvolutionaryAlgorithm(Parameters* params){
	this->params = params;
98
    this->cstats = new CStats();
kruger's avatar
kruger committed
99 100 101 102 103

	CPopulation::initPopulation(params->selectionOperator,params->replacementOperator,params->parentReductionOperator,params->offspringReductionOperator,
			params->selectionPressure,params->replacementPressure,params->parentReductionPressure,params->offspringReductionPressure);

	this->population = new CPopulation(params->parentPopulationSize,params->offspringPopulationSize,
104
			params->pCrossover,params->pMutation,params->pMutationPerGene,params->randomGenerator,params, this->cstats);
kruger's avatar
kruger committed
105 106 107 108 109

	this->currentGeneration = 0;

	this->reduceParents = 0;
	this->reduceOffsprings = 0;
Frédéric Krüger's avatar
Frédéric Krüger committed
110 111
	this->grapher = NULL;
	if(params->plotStats || params->generatePlotScript){
112
		string fichier = params->outputFilename;
maitre's avatar
maitre committed
113 114 115
		fichier.append(".dat");
		remove(fichier.c_str());
	}
Frédéric Krüger's avatar
Frédéric Krüger committed
116
	if(params->generatePlotScript){
117
		string fichier = params->outputFilename;
maitre's avatar
maitre committed
118 119 120
		fichier.append(".plot");
		remove(fichier.c_str());
	}
kruger's avatar
kruger committed
121
	if(params->generateRScript || params->generateCSVFile){
122
		string fichier = params->outputFilename;
kruger's avatar
kruger committed
123
		fichier.append(".csv");
maitre's avatar
maitre committed
124 125 126
		remove(fichier.c_str());
	}
	if(params->generateRScript){
127
		string fichier = params->outputFilename;
maitre's avatar
maitre committed
128 129 130
		fichier.append(".r");
		remove(fichier.c_str());
	}
131
	//#ifndef WIN32 
kruger's avatar
kruger committed
132
	if(params->plotStats){
133 134 135
        string str = "Plotting of the evolution of ";;
        string str2 = this->params->outputFilename;
        str.append(str2);
Frédéric Krüger's avatar
Frédéric Krüger committed
136 137
		//this->grapher = new CGrapher((this->params->offspringPopulationSize*this->params->nbGen)+this->params->parentPopulationSize, (char*)str.c_str());
		this->grapher = new CGrapher(this->params, (char*)str.c_str());
kruger's avatar
kruger committed
138
	}
139
	//#endif
kruger's avatar
kruger committed
140 141 142 143 144 145


	// INITIALIZE SERVER OBJECT ISLAND MODEL
	if(params->remoteIslandModel){
		this->treatedIndividuals = 0;
		this->numberOfClients = 0;
kruger's avatar
kruger committed
146
		this->myClientNumber=0;	
kruger's avatar
kruger committed
147
		this->initializeClients();
148 149
		//if(params->remoteIslandModel)
		server = new CComUDPServer(params->serverPort,0); //1 if debug
kruger's avatar
kruger committed
150
	}
kruger's avatar
kruger committed
151 152
}

kruger's avatar
kruger committed
153
/* DESTRUCTOR */
154
CEvolutionaryAlgorithm::~CEvolutionaryAlgorithm(){
kruger's avatar
kruger committed
155 156 157 158 159 160 161 162 163
	delete population;
        if(this->params->remoteIslandModel){
                delete this->server;
                if(this->numberOfClients>1){
                        for(int i=0; (unsigned)i<this->numberOfClients; i++)
                                delete this->Clients[i];
                        delete this->Clients;
                }
        }
164
}
kruger's avatar
kruger committed
165 166 167 168
void CEvolutionaryAlgorithm::addStoppingCriterion(CStoppingCriterion* sc){
  this->stoppingCriteria.push_back(sc);
}

kruger's avatar
kruger committed
169
/* MAIN FUNCTION TO RUN THE EVOLUTIONARY LOOP */
kruger's avatar
kruger committed
170
void CEvolutionaryAlgorithm::runEvolutionaryLoop(){
maitre's avatar
maitre committed
171
  CIndividual** elitistPopulation;
172

kruger's avatar
kruger committed
173 174 175 176
#ifdef WIN32
   clock_t begin(clock());
#else
  struct timeval begin;
177
  gettimeofday(&begin,0);
kruger's avatar
kruger committed
178 179
#endif

Ogier Maitre's avatar
Ogier Maitre committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
#ifdef INSTRUMENTED
  const char* timing_file_name = "timing.csv";
  FILE* timing_file = NULL;
  if( access(timing_file_name,W_OK)!=0 ){
    // if file does not already exist, start by describing each field
    timing_file = fopen("timing.csv","w");
    fprintf(timing_file,"gen,popSize,init,eval,breeding,reduction\n");
  }
  else{
    timing_file = fopen("timing.csv","a");
  }
  DECLARE_TIME(init);
  DECLARE_TIME_ACC(eval);
  //DECLARE_TIME_ACC(optim);
  DECLARE_TIME_ACC(breeding);
  DECLARE_TIME_ACC(reduction);  

#endif

199
  std::cout << "Population initialisation (Generation 0)... "<< std::endl;
200

Ogier Maitre's avatar
Ogier Maitre committed
201 202 203
  TIME_ST(init);this->initializeParentPopulation();TIME_END(init);

  TIME_ST(eval);
204 205 206 207 208
  if(!INSTEAD_EVAL_STEP)
    this->population->evaluateParentPopulation();
  else
    evale_pop_chunk(population->parents, population->parentPopulationSize);

kruger's avatar
kruger committed
209 210 211
  if(this->params->optimise){
        population->optimiseParentPopulation();
  }
Ogier Maitre's avatar
Ogier Maitre committed
212 213
  TIME_END(eval);
  TIME_ACC(eval);
kruger's avatar
kruger committed
214

kruger's avatar
kruger committed
215 216 217 218 219
  this->population->currentEvaluationNb += this->params->parentPopulationSize;
  if(this->params->printInitialPopulation){
  	std::cout << *population << std::endl;
  }

kruger's avatar
kruger committed
220
  showPopulationStats(begin);
221
  bBest = population->Best;
kruger's avatar
kruger committed
222
  currentGeneration += 1;
kruger's avatar
kruger committed
223

maitre's avatar
maitre committed
224 225 226 227
  //Initialize elitPopulation
  if(params->elitSize)
		elitistPopulation = (CIndividual**)malloc(params->elitSize*sizeof(CIndividual*));	

kruger's avatar
kruger committed
228
  // EVOLUTIONARY LOOP
maitre's avatar
maitre committed
229
  while( this->allCriteria() == false){
kruger's avatar
kruger committed
230 231

    EASEABeginningGenerationFunction(this);
maitre's avatar
maitre committed
232

kruger's avatar
kruger committed
233
    // Sending individuals if remote island model
234
    if(params->remoteIslandModel && this->numberOfClients>0)
kruger's avatar
kruger committed
235
	    this->sendIndividual();
Ogier Maitre's avatar
Ogier Maitre committed
236
    TIME_ST(breeding);
kruger's avatar
kruger committed
237
    population->produceOffspringPopulation();
Ogier Maitre's avatar
Ogier Maitre committed
238 239
    TIME_END(breeding);
    TIME_ACC(breeding);
240

Ogier Maitre's avatar
Ogier Maitre committed
241
    TIME_ST(eval);
242 243 244 245
    if(!INSTEAD_EVAL_STEP)
      population->evaluateOffspringPopulation();
    else
      evale_pop_chunk(population->offsprings, population->offspringPopulationSize);
kruger's avatar
kruger committed
246 247
    population->currentEvaluationNb += this->params->offspringPopulationSize;

kruger's avatar
kruger committed
248 249 250
    if(this->params->optimise){
          population->optimiseOffspringPopulation();
    }
Ogier Maitre's avatar
Ogier Maitre committed
251 252
    TIME_END(eval);
    TIME_ACC(eval);
kruger's avatar
kruger committed
253

maitre's avatar
maitre committed
254
    EASEAGenerationFunctionBeforeReplacement(this);
kruger's avatar
kruger committed
255

maitre's avatar
maitre committed
256 257 258 259 260 261 262 263 264 265 266 267 268
    /* ELITISM */
    if(params->elitSize && this->params->parentPopulationSize>=params->elitSize){
	/* STRONG ELITISM */
	if(params->strongElitism){
		population->strongElitism(params->elitSize, population->parents, this->params->parentPopulationSize, elitistPopulation, params->elitSize);
		population->actualParentPopulationSize -= params->elitSize;
	}
	/* WEAK ELITISM */
	else{
		population->weakElitism(params->elitSize, population->parents, population->offsprings, &(population->actualParentPopulationSize), &(population->actualOffspringPopulationSize), elitistPopulation, params->elitSize);
	}
	
    }
kruger's avatar
kruger committed
269

Ogier Maitre's avatar
Ogier Maitre committed
270
    TIME_ST(reduction);
maitre's avatar
maitre committed
271 272
    if( params->parentReduction )
      population->reduceParentPopulation(params->parentReductionSize);
kruger's avatar
kruger committed
273

maitre's avatar
maitre committed
274
    if( params->offspringReduction )
kruger's avatar
kruger committed
275 276
      population->reduceOffspringPopulation( params->offspringReductionSize );

maitre's avatar
maitre committed
277
    population->reduceTotalPopulation(elitistPopulation);
Ogier Maitre's avatar
Ogier Maitre committed
278 279
    TIME_END(reduction);
    TIME_ACC(reduction);
kruger's avatar
kruger committed
280

281
    population->sortParentPopulation();
282 283
    //if( this->params->printStats  || this->params->generateCSVFile )
    showPopulationStats(begin); // (always calculate stats)
284
    bBest = population->Best;
maitre's avatar
maitre committed
285
    EASEAEndGenerationFunction(this);
kruger's avatar
kruger committed
286

kruger's avatar
kruger committed
287 288 289 290 291
    //Receiving individuals if cluster island model
    if(params->remoteIslandModel){
	this->receiveIndividuals();
    }

kruger's avatar
kruger committed
292 293
    currentGeneration += 1;
  }
294
//#ifdef __linux__
Frédéric Krüger's avatar
Frédéric Krüger committed
295
  //if(this->params->plotStats && this->grapher->valid){
296
  	//outputGraph();
Frédéric Krüger's avatar
Frédéric Krüger committed
297
  	//delete this->grapher;
298 299
  //}
//#endif
kruger's avatar
kruger committed
300

maitre's avatar
maitre committed
301 302
  if(this->params->printFinalPopulation){
  	population->sortParentPopulation();
kruger's avatar
kruger committed
303
  	std::cout << *population << std::endl;
maitre's avatar
maitre committed
304
  }
kruger's avatar
kruger committed
305

kruger's avatar
kruger committed
306 307 308 309 310 311 312 313 314
  //IF SAVING THE POPULATION, ERASE THE OLD FILE
  if(params->savePopulation){
	
	string fichier = params->outputFilename;
	fichier.append(".pop");
	remove(fichier.c_str());
  	population->serializePopulation();
  }

Frédéric Krüger's avatar
Frédéric Krüger committed
315 316
  if(this->params->generatePlotScript || !this->params->plotStats)
	generatePlotScript();
maitre's avatar
maitre committed
317 318 319 320 321 322

  if(this->params->generateRScript)
	generateRScript();
  
  if(params->elitSize)
  	free(elitistPopulation);
323 324

  if(this->params->plotStats){
Frédéric Krüger's avatar
Frédéric Krüger committed
325
      delete this->grapher;
326
  }
Ogier Maitre's avatar
Ogier Maitre committed
327 328 329 330 331 332 333 334 335 336 337

#ifdef INSTRUMENTED
  COMPUTE_TIME(init);
  fprintf(timing_file,"%d,%d,%ld.%06ld,%ld.%06ld,%ld.%06ld,%ld.%06ld\n",
	  currentGeneration, population->parentPopulationSize,
	  init_res.tv_sec,init_res.tv_usec,
	  eval_acc.tv_sec,eval_acc.tv_usec,
	  breeding_acc.tv_sec,breeding_acc.tv_usec,
	  reduction_acc.tv_sec,reduction_acc.tv_usec);
  fclose(timing_file);
#endif
kruger's avatar
kruger committed
338 339 340
}


341 342 343
#ifdef WIN32
void CEvolutionaryAlgorithm::showPopulationStats(clock_t beginTime){
#else
kruger's avatar
kruger committed
344
void CEvolutionaryAlgorithm::showPopulationStats(struct timeval beginTime){
345
#endif
kruger's avatar
kruger committed
346 347

  //Calcul de la moyenne et de l'ecart type
348
  population->Best = population->Worst = population->parents[0];
Ogier Maitre's avatar
Ogier Maitre committed
349
  for(unsigned i=0; i<population->parentPopulationSize; i++){
350
    this->cstats->currentAverageFitness+=population->parents[i]->getFitness();
kruger's avatar
kruger committed
351 352 353 354 355 356

    // here we are looking for the smaller individual's fitness if we are minimizing
    // or the greatest one if we are not
    if( (params->minimizing && population->parents[i]->getFitness()<population->Best->getFitness()) ||
    (!params->minimizing && population->parents[i]->getFitness()>population->Best->getFitness()))
      population->Best=population->parents[i];
357 358 359 360 361 362

    // keep track of worst individual too, for statistical purposes
    if( (params->minimizing && population->parents[i]->getFitness() > population->Worst->getFitness()) ||
    (!params->minimizing && population->parents[i]->getFitness() < population->Worst->getFitness()))
      population->Worst=population->parents[i];

363 364 365 366
    if( params->remoteIslandModel && population->parents[i]->isImmigrant){
        //Count number of Immigrants
       this->cstats->currentNumberOfImmigrants++; 
    }
kruger's avatar
kruger committed
367 368
  }

369
  this->cstats->currentAverageFitness/=population->parentPopulationSize;
kruger's avatar
kruger committed
370

Ogier Maitre's avatar
Ogier Maitre committed
371
  for(unsigned i=0; i<population->parentPopulationSize; i++){
372
    this->cstats->currentStdDev+=(population->parents[i]->getFitness()-this->cstats->currentAverageFitness)*(population->parents[i]->getFitness()-this->cstats->currentAverageFitness);
kruger's avatar
kruger committed
373
  }
374 375
  this->cstats->currentStdDev/=population->parentPopulationSize;
  this->cstats->currentStdDev=sqrt(this->cstats->currentStdDev);
kruger's avatar
kruger committed
376

377 378 379 380 381
#ifdef WIN32
  clock_t end(clock());
  double duration;
  duration = (double)(end-beginTime)/CLOCKS_PER_SEC;
#else
kruger's avatar
kruger committed
382 383 384
  struct timeval end, res;
  gettimeofday(&end,0);
  timersub(&end,&beginTime,&res);
385
#endif
kruger's avatar
kruger committed
386 387 388 389

  //Affichage
  if(params->printStats){
	  if(currentGeneration==0)
390
	    printf("GEN\tTIME\t\tEVAL\t\tBEST      AVG       STDDEV    WORST\n\n");
391
#ifdef WIN32
392
	  printf("%u\t%2.6f\t%u\t%.2e\t%.2e\t%.2e\t%.2e\n",currentGeneration,duration,population->currentEvaluationNb,population->Best->getFitness(),this->cstats->currentAverageFitness,this->cstats->currentStdDev, population->Worst->getFitness());
393
#else
394 395
	    //printf("%d\t%ld.%01ld\t%d\t%.2e\t%.2e\t%.2e\t%.2e\n",(int)currentGeneration,res.tv_sec,res.tv_usec,(int)population->currentEvaluationNb,population->Best->getFitness(),currentAverageFitness,currentSTDEV, population->Worst->getFitness());
	    printf("%d\t%ld.%d\t\t%d\t\t%.2e  %.2e  %.2e  %.2e\n",(int)currentGeneration,res.tv_sec,(int)res.tv_usec/10000,(int)population->currentEvaluationNb,population->Best->getFitness(),this->cstats->currentAverageFitness,this->cstats->currentStdDev, population->Worst->getFitness());
396
#endif
kruger's avatar
kruger committed
397 398
  }

Frédéric Krüger's avatar
Frédéric Krüger committed
399
  if((this->params->plotStats && this->grapher->valid) || this->params->generatePlotScript){
maitre's avatar
maitre committed
400
 	FILE *f;
kruger's avatar
kruger committed
401 402 403
	string fichier = params->outputFilename;
	fichier.append(".dat");
 	f = fopen(fichier.c_str(),"a"); //ajouter .csv
maitre's avatar
maitre committed
404 405
	if(f!=NULL){
	  if(currentGeneration==0)
406
	    fprintf(f,"#GEN\tTIME\t\tEVAL\tBEST\t\tAVG\t\tSTDDEV\t\tWORST\n\n");
407
#ifdef WIN32
408
	  fprintf(f,"%u\t%2.6f\t%u\t%.2e\t%.2e\t%.2e\t%.2e\n",currentGeneration,duration,population->currentEvaluationNb,population->Best->getFitness(),this->cstats->currentAverageFitness,this->cstats->currentStdDev, population->Worst->getFitness());
409
#else
410 411
	    //printf("%d\t%ld.%01ld\t%d\t%.2e\t%.2e\t%.2e\t%.2e\n",(int)currentGeneration,res.tv_sec,res.tv_usec,(int)population->currentEvaluationNb,population->Best->getFitness(),currentAverageFitness,currentSTDEV, population->Worst->getFitness());
	    fprintf(f,"%d\t%ld.%d\t\t%d\t\t%.2e  %.2e  %.2e  %.2e\n",(int)currentGeneration,res.tv_sec,(int)res.tv_usec/10000,(int)population->currentEvaluationNb,population->Best->getFitness(),this->cstats->currentAverageFitness,this->cstats->currentStdDev, population->Worst->getFitness());
412
#endif
maitre's avatar
maitre committed
413 414 415
	  fclose(f);
        }
  }
kruger's avatar
kruger committed
416
  if(params->generateCSVFile || params->generateRScript){ //Generation du fichier CSV;
maitre's avatar
maitre committed
417
 	FILE *f;
418
	string fichier = params->outputFilename;
kruger's avatar
kruger committed
419 420
	fichier.append(".csv");
 	f = fopen(fichier.c_str(),"a"); //ajouter .csv
maitre's avatar
maitre committed
421 422
	if(f!=NULL){
	  if(currentGeneration==0)
423
		fprintf(f,"GEN,TIME,EVAL,BEST,AVG,STDDEV,WORST\n");
424
#ifdef WIN32
425
	  fprintf(f,"%u\t%2.6f\t%u\t%.2e\t%.2e\t%.2e\t%.2e\n",currentGeneration,duration,population->currentEvaluationNb,population->Best->getFitness(),this->cstats->currentAverageFitness,this->cstats->currentStdDev, population->Worst->getFitness());
426
#else
427 428
	    //printf("%d\t%ld.%01ld\t%d\t%.2e\t%.2e\t%.2e\t%.2e\n",(int)currentGeneration,res.tv_sec,res.tv_usec,(int)population->currentEvaluationNb,population->Best->getFitness(),currentAverageFitness,currentSTDEV, population->Worst->getFitness());
	    fprintf(f,"%d\t%ld.%d\t\t%d\t\t%.2e  %.2e  %.2e  %.2e\n",(int)currentGeneration,res.tv_sec,(int)res.tv_usec/10000,(int)population->currentEvaluationNb,population->Best->getFitness(),this->cstats->currentAverageFitness,this->cstats->currentStdDev, population->Worst->getFitness());
429
#endif
maitre's avatar
maitre committed
430 431 432
	  fclose(f);
        }
  }
Frédéric Krüger's avatar
Frédéric Krüger committed
433
  //print grapher
434
  #ifndef WIN32
Frédéric Krüger's avatar
Frédéric Krüger committed
435
  if(this->params->plotStats && this->grapher->valid){
436
	//if(currentGeneration==0)
Frédéric Krüger's avatar
Frédéric Krüger committed
437
	//	fprintf(this->grapher->fWrit,"plot \'%s.dat\' using 3:4 t \'Best Fitness\' w lines ls 1, \'%s.dat\' using 3:5 t  \'Average\' w lines ls 4, \'%s.dat\' using 3:6 t \'StdDev\' w lines ls 3\n", params->outputFilename,params->outputFilename,params->outputFilename);
438
	//else
Frédéric Krüger's avatar
Frédéric Krüger committed
439 440
	//	fprintf(this->grapher->fWrit,"replot\n");
    fprintf(this->grapher->fWrit,"add coordinate:%d;%f;%f;%f\n",population->currentEvaluationNb, population->Best->fitness, this->cstats->currentAverageFitness, this->cstats->currentStdDev);
441 442
    if(this->params->remoteIslandModel){
        if(population->Best->isImmigrant){
Frédéric Krüger's avatar
Frédéric Krüger committed
443
            fprintf(this->grapher->fWrit,"set immigrant\n");
444
        }
Frédéric Krüger's avatar
Frédéric Krüger committed
445
        fprintf(this->grapher->fWrit,"add stat:%d;%d;%d\n",currentGeneration, this->cstats->currentNumberOfImmigrants, this->cstats->currentNumberOfImmigrantReproductions);
446 447
    }
    if(currentGeneration==0){
Frédéric Krüger's avatar
Frédéric Krüger committed
448
        fprintf(this->grapher->fWrit,"paint\n");
449 450
    }
    else{
Frédéric Krüger's avatar
Frédéric Krüger committed
451
        fprintf(this->grapher->fWrit,"repaint\n");
452
    }
Frédéric Krüger's avatar
Frédéric Krüger committed
453
	fflush(this->grapher->fWrit);
kruger's avatar
kruger committed
454 455
 }
#endif
456 457
 
#ifdef __linux__
Frederic Kruger's avatar
Frederic Kruger committed
458 459
  double elapsedTime = res.tv_sec + 0.0;
  double micSec = res.tv_usec + 0.0;
maitre's avatar
maitre committed
460

Frederic Kruger's avatar
Frederic Kruger committed
461 462 463 464 465 466 467
  while(micSec>1){
	micSec /= 10.;
  }
  elapsedTime += micSec + 0.0;


  params->timeCriterion->setElapsedTime(elapsedTime);
468 469 470 471 472

#endif

  //Reset Current Gen Stats
  this->cstats->resetCurrentStats();
maitre's avatar
maitre committed
473 474
}

kruger's avatar
kruger committed
475 476
//REMOTE ISLAND MODEL FUNCTIONS
void CEvolutionaryAlgorithm::initializeClients(){
477
	/*int clientNumber=0;
kruger's avatar
kruger committed
478 479
	char (*clients)[16] = (char(*)[16])calloc(1,sizeof(char)*16);
	
480
	cout << "Reading IP address file: " << this->params->ipFile << endl;
kruger's avatar
kruger committed
481
	ifstream IP_File(this->params->ipFile);
kruger's avatar
kruger committed
482 483 484
	string line;
	while(getline(IP_File, line)){
		if(!isLocalMachine(line.c_str())){
kruger's avatar
kruger committed
485 486 487 488 489 490 491 492
			memmove(clients[this->numberOfClients],line.c_str(),sizeof(char)*16);
			this->numberOfClients++;
			clients = (char(*)[16])realloc(clients,sizeof(char)*16*(this->numberOfClients*16));
			clientNumber++;
		}
		else{
			this->myClientNumber = clientNumber;	
		}
493 494
	}*/
    this->refreshClient();
kruger's avatar
kruger committed
495

496
	/*if(this->numberOfClients>0){
497 498 499 500 501
		this->Clients = (CComUDPClient**)malloc(this->numberOfClients*sizeof(CComUDPClient*));
		for(int i=0; i<(signed)this->numberOfClients; i++){
			this->Clients[i] = new CComUDPClient(2909,(const char*)clients[i],0);
		}
	}
502 503 504 505
	else{*/
    if(this->numberOfClients<=0){
		cout << "***WARNING***\nNo islands to communicate with." << endl;
	//	params->remoteIslandModel=0;
kruger's avatar
kruger committed
506
	}
507 508 509 510 511 512 513 514
}

void CEvolutionaryAlgorithm::refreshClient(){
    unsigned no_client;
    this->Clients = parse_file(this->params->ipFile,&no_client, this->params->serverPort);

    cout << "ip file : " << this->params->ipFile << " contains " << no_client << " client ip(s)" << endl;
    this->numberOfClients = no_client;
kruger's avatar
kruger committed
515 516 517 518
}

void CEvolutionaryAlgorithm::sendIndividual(){
	//Sending an individual every n generations	
519
	if(globalRandomGenerator->random(0.0,1.0)<=params->migrationProbability){
Frederic Kruger's avatar
Frederic Kruger committed
520
	//if((this->currentGeneration+this->myClientNumber)%3==0 && this->currentGeneration!=0){
kruger's avatar
kruger committed
521
		//cout << "I'm going to send an Individual now" << endl;
Frederic Kruger's avatar
Frederic Kruger committed
522
		this->population->selectionOperator->initialize(this->population->parents, params->selectionPressure, this->population->actualParentPopulationSize);
Ogier Maitre's avatar
Ogier Maitre committed
523
		//unsigned index = this->population->selectionOperator->selectNext(this->population->actualParentPopulationSize);
kruger's avatar
kruger committed
524 525 526
	
		//selecting a client randomly
		int client = globalRandomGenerator->getRandomIntMax(this->numberOfClients);
Frederic Kruger's avatar
Frederic Kruger committed
527
		//for(int client=0; client<this->numberOfClients; client++){
528 529
		cout << "    Going to send an individual to client " << client << endl;
		cout << "    His IP is " << this->Clients[client]->getIP() << " and his port is " << this->Clients[client]->getPort() <<endl;
530
		//cout << "Sending individual " << index << " to client " << client << " now" << endl;
kruger's avatar
kruger committed
531
		//cout << this->population->parents[index]->serialize() << endl;
532
		this->Clients[client]->CComUDP_client_send((char*)bBest->serialize().c_str());
kruger's avatar
kruger committed
533 534 535 536 537 538 539 540
	}
}

void CEvolutionaryAlgorithm::receiveIndividuals(){
	//Checking every generation for received individuals
	if(this->treatedIndividuals<(unsigned)this->server->nb_data){
		//cout << "number of received individuals :" << this->server->nb_data << endl;
		//cout << "number of treated individuals :" << this->treatedIndividuals << endl;
Frederic Kruger's avatar
Frederic Kruger committed
541
		CSelectionOperator *antiTournament = getSelectionOperator("Tournament",!this->params->minimizing, globalRandomGenerator);		
kruger's avatar
kruger committed
542 543 544 545

		//Treating all the individuals before continuing
		while(this->treatedIndividuals < (unsigned)this->server->nb_data){
			//selecting the individual to erase
Frederic Kruger's avatar
Frederic Kruger committed
546 547
			antiTournament->initialize(this->population->parents, 7, this->population->actualParentPopulationSize);
			unsigned index = antiTournament->selectNext(this->population->actualParentPopulationSize);
548 549
			
			//We're selecting the worst element to replace
Frederic Kruger's avatar
Frederic Kruger committed
550
			//size_t index = this->population->getWorstIndividualIndex(this->population->parents);
kruger's avatar
kruger committed
551 552 553 554 555 556

			//cout << "old individual fitness :" << this->population->parents[index]->fitness << endl;
			//cout << "old Individual :" << this->population->parents[index]->serialize() << endl;
			this->server->read_data_lock();
			string line = this->server->parm->data[this->treatedIndividuals].data;
			this->population->parents[index]->deserialize(line);
557 558 559
            //TAG THE INDIVIDUAL AS IMMIGRANT
            this->population->parents[index]->isImmigrant = true;

kruger's avatar
kruger committed
560 561 562 563 564 565 566
			this->server->read_data_unlock();
			//cout << "new Individual :" << this->population->parents[index]->serialize() << endl;
			this->treatedIndividuals++;
		}
	}
}

maitre's avatar
maitre committed
567
void CEvolutionaryAlgorithm::outputGraph(){
Frédéric Krüger's avatar
Frédéric Krüger committed
568 569 570 571 572 573 574
    /*  	fprintf(this->grapher->fWrit,"set term png\n");
      	fprintf(this->grapher->fWrit,"set output \"%s\"\n",params->plotOutputFilename);
	fprintf(this->grapher->fWrit,"set xrange[0:%d]\n",(int)population->currentEvaluationNb);
	fprintf(this->grapher->fWrit,"set xlabel \"Number of Evaluations\"\n");
        fprintf(this->grapher->fWrit,"set ylabel \"Fitness\"\n");
        fprintf(this->grapher->fWrit,"replot \n");
	fflush(this->grapher->fWrit);*/
maitre's avatar
maitre committed
575 576
}

Frédéric Krüger's avatar
Frédéric Krüger committed
577
void CEvolutionaryAlgorithm::generatePlotScript(){
maitre's avatar
maitre committed
578
	FILE* f;
579
	string fichier = this->params->outputFilename;
maitre's avatar
maitre committed
580 581 582 583
	fichier.append(".plot");
	f = fopen(fichier.c_str(),"a");
	fprintf(f,"set term png\n");
	fprintf(f,"set output \"%s\"\n",params->plotOutputFilename);
584
	fprintf(f,"set xrange[0:%d]\n",(int)population->currentEvaluationNb);
maitre's avatar
maitre committed
585 586 587 588 589 590 591 592
	fprintf(f,"set xlabel \"Number of Evaluations\"\n");
        fprintf(f,"set ylabel \"Fitness\"\n");
	fprintf(f,"plot \'%s.dat\' using 3:4 t \'Best Fitness\' w lines, \'%s.dat\' using 3:5 t  \'Average\' w lines, \'%s.dat\' using 3:6 t \'StdDev\' w lines\n", params->outputFilename,params->outputFilename,params->outputFilename);
	fclose(f);	
}

void CEvolutionaryAlgorithm::generateRScript(){
	FILE* f;
593
	string fichier = this->params->outputFilename;
maitre's avatar
maitre committed
594 595 596 597
	fichier.append(".r");
	f=fopen(fichier.c_str(),"a");
	fprintf(f,"#Plotting for R\n"),
	fprintf(f,"png(\"%s\")\n",params->plotOutputFilename);
kruger's avatar
kruger committed
598
	fprintf(f,"data <- read.table(\"./%s.csv\",sep=\",\")\n",params->outputFilename);
599
	fprintf(f,"plot(0, type = \"n\", main = \"Plot Title\", xlab = \"Number of Evaluations\", ylab = \"Fitness\", xlim = c(0,%d) )\n",(int)population->currentEvaluationNb);
maitre's avatar
maitre committed
600 601 602 603 604 605 606
	fprintf(f,"grid() # add grid\n");
	fprintf(f,"lines(data[,3], data[,4], lty = 1) #draw first dataset\n");
	fprintf(f,"lines(data[,3], data[,5], lty = 2) #draw second dataset\n");
	fprintf(f,"lines(data[,3], data[,6], lty = 3) #draw third dataset\n");
	fprintf(f,"legend(\"topright\", c(\"Best Fitness\", \"Average\", \"StdDev\"), lty = c(1, 2, 3) )\n");
	fclose(f);
	
kruger's avatar
kruger committed
607 608 609 610
}

bool CEvolutionaryAlgorithm::allCriteria(){

Ogier Maitre's avatar
Ogier Maitre committed
611
	for( unsigned i=0 ; i<stoppingCriteria.size(); i++ ){
kruger's avatar
kruger committed
612
		if( stoppingCriteria.at(i)->reached() ){
613
			std::cout << "Stopping criterion reached" << std::endl;
kruger's avatar
kruger committed
614 615 616 617
			return true;
		}
	}
	return false;
kruger's avatar
kruger committed
618
}
619 620

#ifdef WIN32
kruger's avatar
kruger committed
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
int gettimeofday
(struct timeval* tp, void* tzp) {
	DWORD t;
	t = timeGetTime();
	tp->tv_sec = t / 1000;
	tp->tv_usec = t % 1000;
	return 0;
}

void timersub( const timeval * tvp, const timeval * uvp, timeval* vvp )
{
	vvp->tv_sec = tvp->tv_sec - uvp->tv_sec;
	vvp->tv_usec = tvp->tv_usec - uvp->tv_usec;
	if( vvp->tv_usec < 0 )
	{
		--vvp->tv_sec;
		vvp->tv_usec += 1000000;
	}
} 
640 641
#endif