Commit 8630340f authored by kruger's avatar kruger

Avec la lib cette fois

parent 39b21c8d
This diff is collapsed.
This diff is collapsed.
#include <math.h>
#include "include/CCuda.h"
#define NB_MP 16
CCuda::CCuda(size_t parentSize, size_t offSize, size_t individualImplSize){
this->sizeOfIndividualImpl = individualImplSize;
this->cudaParentBuffer = (void*)malloc(this->sizeOfIndividualImpl*parentSize);
this->cudaOffspringBuffer = (void*)malloc(this->sizeOfIndividualImpl*offSize);
}
CCuda::~CCuda(){
}
inline size_t partieEntiereSup(float E){
int fl = floor(E);
if(fl==E)
return E;
else
return floor(E=1);
}
inline int puissanceDeuxSup(float n){
int tmp=2;
while(tmp<n) tmp*=2;
return tmp;
}
bool repartition(size_t popSize, size_t* nbBlock, size_t* nbThreadPB, size_t* nbThreadLB, size_t nbMP, size_t maxBlockSize){
(*nbThreadLB) = 0;
//DEBUG_PRT("repartition : %d",popSize);
if( ((float)popSize / (float)nbMP) <= maxBlockSize ){
//la population repartie sur les MP tient dans une bloc par MP
(*nbThreadPB) = partieEntiereSup( (float)popSize/(float)nbMP);
(*nbBlock) = popSize/(*nbThreadPB);
if( popSize%nbMP != 0 ){
//on fait MP-1 block de equivalent et un plus petit
(*nbThreadLB) = popSize - (*nbThreadPB)*(*nbBlock);
}
}
else{
//la population est trop grande pour etre repartie sur les MP
//directement
//(*nbBlock) = partieEntiereSup( (float)popSize/((float)maxBlockSize*NB_MP));
(*nbBlock) = puissanceDeuxSup( (float)popSize/((float)maxBlockSize*NB_MP));
(*nbBlock) *= NB_MP;
(*nbThreadPB) = popSize/(*nbBlock);
if( popSize%maxBlockSize!=0){
(*nbThreadLB) = popSize - (*nbThreadPB)*(*nbBlock);
// Le rest est trop grand pour etre place dans un seul block (c'est possible uniquement qd
// le nombre de block depasse maxBlockSize
while( (*nbThreadLB) > maxBlockSize ){
//on augmente le nombre de blocs principaux jusqu'a ce que nbthreadLB retombe en dessous de maxBlockSize
//(*nbBlock) += nbMP;
(*nbBlock) *= 2;
(*nbThreadPB) = popSize/(*nbBlock);
(*nbThreadLB) = popSize - (*nbThreadPB)*(*nbBlock);
}
}
}
if((((*nbBlock)*(*nbThreadPB) + (*nbThreadLB)) == popSize) && ((*nbThreadLB) <= maxBlockSize) && ((*nbThreadPB) <= maxBlockSize))
return true;
else
return false;
}
#ifdef WIN32
#pragma comment(lib, "WinMM.lib")
#endif
/*
* CEvolutionaryAlgorithm.cpp
*
* Created on: 22 juin 2009
* Author: maitre
*/
#include "include/CEvolutionaryAlgorithm.h"
#include <string>
#ifndef WIN32
#include <sys/time.h>
#endif
#ifdef WIN32
#include <windows.h>
#endif
#include <time.h>
#include <math.h>
#include "include/CIndividual.h"
#include "include/Parameters.h"
#include "include/CGnuplot.h"
#include "include/global.h"
extern CRandomGenerator* globalRandomGenerator;
void EASEABeginningGenerationFunction(CEvolutionaryAlgorithm* evolutionaryAlgorithm);
void EASEAEndGenerationFunction(CEvolutionaryAlgorithm* evolutionaryAlgorithm);
/**
* @DEPRECATED the next contructor has to be used instead of this one.
*/
CEvolutionaryAlgorithm::CEvolutionaryAlgorithm( size_t parentPopulationSize,
size_t offspringPopulationSize,
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;
}
CEvolutionaryAlgorithm::CEvolutionaryAlgorithm(Parameters* params){
this->params = params;
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,
params->pCrossover,params->pMutation,params->pMutationPerGene,params->randomGenerator,params);
this->currentGeneration = 0;
this->reduceParents = 0;
this->reduceOffsprings = 0;
this->gnuplot = NULL;
#ifdef __linux__
remove("stats.dat");
if(params->plotStats){
this->gnuplot = new CGnuplot();
if(!this->gnuplot->valid)
printf("Attention, erreur lors de l'utilisation de gnulplot, l'algo va continuer sans plot");
}
#endif
}
void CEvolutionaryAlgorithm::addStoppingCriterion(CStoppingCriterion* sc){
this->stoppingCriteria.push_back(sc);
}
void CEvolutionaryAlgorithm::runEvolutionaryLoop(){
std::vector<CIndividual*> tmpVect;
std::cout << "Parent's population initializing "<< std::endl;
this->initializeParentPopulation();
this->population->evaluateParentPopulation();
this->population->currentEvaluationNb += this->params->parentPopulationSize;
if(this->params->printInitialPopulation){
std::cout << *population << std::endl;
}
struct timeval begin;
gettimeofday(&begin,NULL);
while( this->allCriteria() == false ){
EASEABeginningGenerationFunction(this);
population->produceOffspringPopulation();
population->evaluateOffspringPopulation();
population->currentEvaluationNb += this->params->offspringPopulationSize;
//EASEAEndGenerationFunction(this);
if( params->parentReduction )
population->reduceParentPopulation(params->parentReductionSize);
if( params->offspringReduction )
population->reduceOffspringPopulation( params->offspringReductionSize );
population->reduceTotalPopulation();
EASEAEndGenerationFunction(this);
showPopulationStats(begin);
currentGeneration += 1;
}
population->sortParentPopulation();
if(this->params->printFinalPopulation)
std::cout << *population << std::endl;
std::cout << "Generation : " << currentGeneration << std::endl;
#ifdef __linux__
if(this->params->plotStats && this->gnuplot->valid)
delete this->gnuplot;
#endif
}
void CEvolutionaryAlgorithm::showPopulationStats(struct timeval beginTime){
float currentAverageFitness=0.0;
float currentSTDEV=0.0;
//Calcul de la moyenne et de l'ecart type
population->Best=population->parents[0];
for(size_t i=0; i<population->parentPopulationSize; i++){
currentAverageFitness+=population->parents[i]->getFitness();
// 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];
}
currentAverageFitness/=population->parentPopulationSize;
for(size_t i=0; i<population->parentPopulationSize; i++){
currentSTDEV+=(population->parents[i]->getFitness()-currentAverageFitness)*(population->parents[i]->getFitness()-currentAverageFitness);
}
currentSTDEV/=population->parentPopulationSize;
currentSTDEV=sqrt(currentSTDEV);
struct timeval end, res;
gettimeofday(&end,0);
timersub(&end,&beginTime,&res);
//Affichage
if(params->printStats){
if(currentGeneration==0)
printf("GEN\tTIME\t\tEVAL\tBEST\t\tAVG\t\tSTDEV\n\n");
printf("%lu\t%ld.%06ld\t%lu\t%.15e\t%.15e\t%.15e\n",currentGeneration,res.tv_sec,res.tv_usec,population->currentEvaluationNb,population->Best->getFitness(),currentAverageFitness,currentSTDEV);
}
//print Gnuplot
#ifdef __linux__
if(this->params->plotStats && this->gnuplot->valid){
FILE *f;
f = fopen("stats.dat","a");
if(f!=NULL){
fprintf(f,"%lu\t%d.%06d\t%lu\t%.15e\t%.15e\t%.15e\n",currentGeneration,res.tv_sec,res.tv_usec,population->currentEvaluationNb, population->Best->getFitness(),currentAverageFitness,currentSTDEV);
fclose(f);
}
if(currentGeneration==0)
fprintf(this->gnuplot->fWrit,"plot \'stats.dat\' using 3:4 t \'Best Fitness\' w lines, \'stats.dat\' using 3:5 t \'Average\' w lines, \'stats.dat\' using 3:6 t \'StdDev\' w lines\n");
else if((currentGeneration+1)==(*EZ_NB_GEN)){
fprintf(this->gnuplot->fWrit,"set term png\n");
fprintf(this->gnuplot->fWrit,"set output \"plot.png\"\n");
fprintf(this->gnuplot->fWrit,"replot \n");
}
else
fprintf(this->gnuplot->fWrit,"replot\n");
fflush(this->gnuplot->fWrit);
}
#endif
}
bool CEvolutionaryAlgorithm::allCriteria(){
for( size_t i=0 ; i<stoppingCriteria.size(); i++ ){
if( stoppingCriteria.at(i)->reached() ){
std::cout << "Stopping criterion reached : " << i << std::endl;
return true;
}
}
return false;
}
#ifdef WIN32
int gettimeofday
(struct timeval* tp, void* tzp) {
DWORD t;
t = timeGetTime();
tp->tv_sec = t / 1000;
tp->tv_usec = t % 1000;
/* 0 indicates success. */
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;
}
}
#endif
#include "include/CGnuplot.h"
CGnuplot::CGnuplot(){
#ifdef __linux__
int toFils[2];
int toPere[2];
int sonPid;
if(pipe(toFils)<0){
perror("PipeComOpen: Creating pipes");
this->valid=0;
return;
}
if(pipe(toPere)<0){
perror("PipeComOpen: Creating pipes");
this->valid=0;
return;
}
switch((sonPid=vfork())){
case -1:
perror("PipeComOpen: fork failed");
this->valid=0;
break;
case 0:
/* --- here's the son --- */
if(dup2(toFils[0], fileno(stdin))<0){
perror("PipeComOpen(son): could not connect");
this->valid=0;
return;
//abort();
}
if(dup2(toPere[1], fileno(stdout))<0){
perror("PipeComOpen(son): could not connect");
this->valid=0;
return;
//abort();
}
char *arg[2];
arg[0] = "-persist";
arg[1] = 0;
if(execvp("gnuplot",arg)<0){
perror("gnuplot not installed, please change plotStats parameter");
//abort();
this->valid=0;
break;
}
break;
default:
this->fWrit = (FILE *)fdopen(toFils[1],"w");
this->fRead = (FILE *)fdopen(toPere[0],"r");
this->pid = sonPid;
this->valid = 1;
fprintf(this->fWrit,"set term x11 persist\n");
fprintf(this->fWrit,"set grid\n");
fflush(this->fWrit);
}
#endif
}
CGnuplot::~CGnuplot(){
#ifdef __linux__
fprintf(this->fWrit,"quit\n");
fclose(this->fRead);
fclose(this->fWrit);
#endif
}
/*
* CIndividual.cpp
*
* Created on: 23 juin 2009
* Author: maitre
*/
#include "include/CIndividual.h"
CIndividual::CIndividual() {
// TODO Auto-generated constructor stub
}
CIndividual::~CIndividual() {
// TODO Auto-generated destructor stub
}
/*
* COptionParser.cpp
*
* Created on: 22 juin 2009
* Author: maitre
*/
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
po::variables_map vm;
po::variables_map vm_file;
using namespace std;
string setVariable(string argumentName, string defaultValue, po::variables_map vm, po::variables_map vm_file){
string ret;
if( vm.count(argumentName) ){
ret = vm[argumentName].as<string>();
cout << argumentName << " is declared in user command line as "<< ret << endl;
}
else if( vm_file.count(argumentName) ){
ret = vm_file[argumentName].as<string>();
cout << argumentName << " is declared configuration file as "<< ret << endl;
}
else {
ret = defaultValue;
cout << argumentName << " is not declared, default value is "<< ret<< endl;
}
return ret;
}
int setVariable(string argumentName, int defaultValue, po::variables_map vm, po::variables_map vm_file ){
int ret;
if( vm.count(argumentName) ){
ret = vm[argumentName].as<int>();
cout << argumentName << " is declared in user command line as "<< ret << endl;
}
else if( vm_file.count(argumentName) ){
ret = vm_file[argumentName].as<int>();
cout << argumentName << " is declared configuration file as "<< ret << endl;
}
else {
ret = defaultValue;
cout << argumentName << " is not declared, default value is "<< ret<< endl;
}
return ret;
}
int loadParametersFile(const string& filename, char*** outputContainer){
FILE* paramFile = fopen(filename.c_str(),"r");
char buffer[512];
vector<char*> tmpContainer;
char* padding = (char*)malloc(sizeof(char));
padding[0] = 0;
tmpContainer.push_back(padding);
while( fgets(buffer,512,paramFile)){
for( size_t i=0 ; i<512 ; i++ )
if( buffer[i] == '#' || buffer[i] == '\n' || buffer[i] == '\0' || buffer[i]==' '){
buffer[i] = '\0';
break;
}
int str_len;
if( (str_len = strlen(buffer)) ){
cout << "line : " <<buffer << endl;
char* nLine = (char*)malloc(sizeof(char)*(str_len+1));
strcpy(nLine,buffer);
tmpContainer.push_back(nLine);
}
}
(*outputContainer) = (char**)malloc(sizeof(char*)*tmpContainer.size());
for ( size_t i=0 ; i<tmpContainer.size(); i++)
(*outputContainer)[i] = tmpContainer.at(i);
fclose(paramFile);
return tmpContainer.size();
}
void parseArguments(const char* parametersFileName, int ac, char** av,
po::variables_map& vm, po::variables_map& vm_file){
char** argv;
int argc = loadParametersFile(parametersFileName,&argv);
po::options_description desc("Allowed options ");
desc.add_options()
("help", "produce help message")
("compression", po::value<int>(), "set compression level")
("seed", po::value<int>(), "set the global seed of the pseudo random generator")
("popSize",po::value<int>(),"set the population size")
("nbOffspring",po::value<int>(),"set the offspring population size")
("parentReductionSize",po::value<int>(),"set the reduction size for parent population")
("offspringReductionSize",po::value<int>(),"set the reduction size for offspring population")
("elite",po::value<int>(),"Nb of elite parents (absolute)")
("eliteType",po::value<int>(),"Strong (1) or weak (1)")
("nbGen",po::value<int>(),"Set the number of generation")
("surviveParents",po::value<int>()," Nb of surviving parents (absolute)")
("surviveOffsprings",po::value<int>()," Nb of surviving offsprings (absolute)")
("outputfile",po::value<string>(),"Set an output file for the final population (default : none)")
("inputfile",po::value<string>(),"Set an input file for the initial population (default : none)")
("printStats",po::value<int>(),"Print the Stats (default : 1)")
("plotStats",po::value<int>(),"Plot the Stats with gnuplot (default : 0)")
("printInitialPopulation",po::value<int>(),"Prints the initial population (default : 0)")
("printFinalPopulation",po::value<int>(),"Prints the final population (default : 0)")
("u1",po::value<string>(),"User defined parameter 1")
("u2",po::value<string>(),"User defined parameter 2")
("u3",po::value<string>(),"User defined parameter 3")
("u4",po::value<string>(),"User defined parameter 4")
;
try{
po::store(po::parse_command_line(ac, av, desc,0), vm);
po::store(po::parse_command_line(argc, argv, desc,0), vm_file);
}
catch(po::unknown_option& e){
cerr << "Unknown option : " << e.what() << endl;
cout << desc << endl;
exit(1);
}
po::notify(vm);
po::notify(vm_file);
if (vm.count("help")) {
cout << desc << "\n";
exit(1);
}
for( int i = 0 ; i<argc ; i++ )
free(argv[i]);
free(argv);
}
void parseArguments(const char* parametersFileName, int ac, char** av){
parseArguments(parametersFileName,ac,av,vm,vm_file);
}
int setVariable(const string optionName, int defaultValue){
return setVariable(optionName,defaultValue,vm,vm_file);
}
string setVariable(const string optionName, string defaultValue){
return setVariable(optionName,defaultValue,vm,vm_file);
}
This diff is collapsed.
/*
* CRandomGenerator.cpp
*
* Created on: 22 juin 2009
* Author: maitre
*/
#include "include/CRandomGenerator.h"
#include "include/global.h"
#include <stdlib.h>
CRandomGenerator::CRandomGenerator(unsigned int seed){
srand(seed);
}
int CRandomGenerator::randInt(){
return rand();
}
bool CRandomGenerator::tossCoin(){
int rVal = rand();
if( rVal >=(RNDMAX/2))
return true;
else return false;
}
bool CRandomGenerator::tossCoin(float bias){
int rVal = rand();
if( rVal <=(RNDMAX*bias) )
return true;
else return false;
}
int CRandomGenerator::randInt(int min, int max){
int rValue = (((float)rand()/RNDMAX))*(max-min);
//DEBUG_PRT("Int Random Value : %d",min+rValue);
return rValue+min;
}
int CRandomGenerator::random(int min, int max){
return randInt(min,max);
}
float CRandomGenerator::randFloat(float min, float max){
float rValue = (((float)rand()/RNDMAX))*(max-min);
//DEBUG_PRT("Float Random Value : %f",min+rValue);
return rValue+min;
}
float CRandomGenerator::random(float min, float max){
return randFloat(min,max);
}