From 7e904c5db4f90c0fc52e48d23e47b52052a6cb8d Mon Sep 17 00:00:00 2001 From: maitre Date: Mon, 27 Apr 2009 10:49:12 +0200 Subject: [PATCH] Using static library (exe could be placed in /usr/bin), std_mo (dual objective) --- Easea.h | 7 + EaseaLex.l | 5 +- EaseaParse.y | 11 +- alexyacc/makefile | 5 + makefile | 39 +- tpl/STD_MO.tpl | 1719 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1780 insertions(+), 6 deletions(-) create mode 100644 tpl/STD_MO.tpl diff --git a/Easea.h b/Easea.h index ec6290d..0d3cdbf 100644 --- a/Easea.h +++ b/Easea.h @@ -23,6 +23,12 @@ Centre de Math #define DREAM 3 #define CUDA 4 #define STD 5 + +#define STD_FLAVOR_SO 0 +#define STD_FLAVOR_MO 1 +#define CUDA_FLAVOR_SO 0 +#define CUDA_FLAVOR_MO 0 + #define UNIX 1 #define WINDOWS 2 #define UNKNOWN_OS 3 @@ -46,6 +52,7 @@ extern char sMIG_SEL[], sMIGRATOR[], sIMMIG_SEL[],sMIG_TARGET_SELECTOR[]; extern int nWARNINGS, nERRORS; extern int TARGET, OPERATING_SYSTEM; +extern int TARGET_FLAVOR; // Prototypes extern int mystricmp(char *, char *); diff --git a/EaseaLex.l b/EaseaLex.l index 1610f52..c0eb349 100644 --- a/EaseaLex.l +++ b/EaseaLex.l @@ -1820,7 +1820,10 @@ int CEASEALexer::create(CEASEAParser* pParser, CSymbolTable* pSymTable) } } if (TARGET==STD){ - strcat(sTemp,"STD.tpl"); + if(TARGET_FLAVOR == STD_FLAVOR_SO) + strcat(sTemp,"STD.tpl"); + else + strcat(sTemp,"STD_MO.tpl"); if (!(yyin = fpTemplateFile = fopen(sTemp, "r"))){ fprintf(stderr,"\n*** Could not open %s.\n",sTemp); fprintf(stderr,"*** Please modify the EZ_PATH environment variable.\n"); diff --git a/EaseaParse.y b/EaseaParse.y index ffb8b35..674e4c5 100644 --- a/EaseaParse.y +++ b/EaseaParse.y @@ -24,7 +24,7 @@ char sLOWER_CASE_PROJECT_NAME[1000]; char sEZ_FILE_NAME[1000]; char sEO_DIR[1000]; char sEZ_PATH[1000]; -int TARGET; +int TARGET,TARGET_FLAVOR; int OPERATING_SYSTEM; int nWARNINGS=0; int nERRORS=0; @@ -1327,7 +1327,14 @@ int main(int argc, char *argv[]){ else if (!mystricmp(sTemp,"galib")) TARGET=GALIB; else if (!mystricmp(sTemp,"dream")) TARGET=DREAM; else if (!mystricmp(sTemp,"cuda")) TARGET=CUDA; - else if (!mystricmp(sTemp,"std")) TARGET=STD; + else if (!mystricmp(sTemp,"std")) { + TARGET=STD; + TARGET_FLAVOR = STD_FLAVOR_SO; + } + else if (!mystricmp(sTemp,"std_mo")) { + TARGET=STD; + TARGET_FLAVOR = STD_FLAVOR_MO; + } else if (!mystricmp(sTemp,"v")) bVERBOSE=true; else if (!mystricmp(sTemp,"path")) { if (argv[++nParamNb][0]=='"') { diff --git a/alexyacc/makefile b/alexyacc/makefile index 74c3dfd..7cfddff 100644 --- a/alexyacc/makefile +++ b/alexyacc/makefile @@ -10,6 +10,11 @@ yycunput.o yycuoflw.o yycwipe.o yycwork.o yycwrap.o CPPC = g++ CPPFLAGS = -Iinclude/ LIB_NAME=libalex.so +STATIC_LIB_NAME = libalex.a + +$(STATIC_LIB_NAME): $(OBJS) + ar -r $@ $(OBJS) && ranlib $@ + $(LIB_NAME): $(OBJS) $(CPPC) -shared -o $@ $^ diff --git a/makefile b/makefile index 65ee9c2..1298484 100644 --- a/makefile +++ b/makefile @@ -4,12 +4,41 @@ CPPC = g++ LDFLAGS = -$(EXEC):EaseaSym.o EaseaParse.o EaseaLex.o alexyacc/libalex.so + +$(EXEC):EaseaSym.o EaseaParse.o EaseaLex.o alexyacc/libalex.a $(CPPC) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ + # + # Congratulations ! It looks like you compiled EASEA successfully. + # + # Generated files depend on libboost-program-options, + # be sure that the development version of this library + # is installed on you system : + # For example, on ubuntu : + # sudo apt-get install libboost-program-options-dev + # + # Easea could be moved to a bin directory or included in the PATH + # as long as users have defined a EZ_PATH environment variable + # pointing to the tpl/ directory. + # To do this temporarly type : + # export EZ_PATH=`pwd`/tpl/ + # Or define EZ_PATH in your bashrc file (for bash users) : + # For example : + # export EZ_PATH=/path/to/easea/directory/tpl/ + # + # Otherwise you can use easea from this directory by typing : + # For example : + # ./easea examples/weierstrass/weierstrass.ez + # Go to the taget directory and type make + # + # Thanks for using EASEA. + # + +# $(EXEC):EaseaSym.o EaseaParse.o EaseaLex.o alexyacc/libalex.so +# $(CPPC) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ -$(EXEC)_bin:EaseaSym.o EaseaParse.o EaseaLex.o - $(CPPC) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ -lalex +# $(EXEC)_bin:EaseaSym.o EaseaParse.o EaseaLex.o +# $(CPPC) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ -lalex @@ -23,6 +52,10 @@ EaseaParse.o: EaseaParse.cpp EaseaLex.cpp alexyacc/libalex.so:alexyacc/*.cpp cd alexyacc && make libalex.so +alexyacc/libalex.a:alexyacc/*.cpp + cd alexyacc && make libalex.a + + clean: rm -f *.o $(EXEC) $(EXEC)_bin cd alexyacc && make clean diff --git a/tpl/STD_MO.tpl b/tpl/STD_MO.tpl new file mode 100644 index 0000000..47ca97d --- /dev/null +++ b/tpl/STD_MO.tpl @@ -0,0 +1,1719 @@ +\TEMPLATE_START/** + This is program entry for standard multiobjective template for EASEA + +*/ +\ANALYSE_PARAMETERS +using namespace std; +#include +#include "EASEATools.hpp" +#include "EASEAIndividual.hpp" +#include + +RandomGenerator* globalRandomGenerator; + + +int main(int argc, char** argv){ + + + parseArguments("EASEA.prm",argc,argv); + + size_t parentPopulationSize = setVariable("popSize",\POP_SIZE); + size_t offspringPopulationSize = setVariable("nbOffspring",\OFF_SIZE); + float pCrossover = \XOVER_PROB; + float pMutation = \MUT_PROB; + float pMutationPerGene = 0.05; + + time_t seed = setVariable("seed",time(0)); + globalRandomGenerator = new RandomGenerator(seed); + + std::cout << "Seed is : " << seed << std::endl; + + SelectionOperator* selectionOperator = new \SELECTOR; + SelectionOperator* replacementOperator = new \RED_FINAL; + float selectionPressure = \SELECT_PRM; + float replacementPressure = \RED_FINAL_PRM; + string outputfile = setVariable("outputfile",""); + string inputfile = setVariable("inputfile",""); + + EASEAInit(argc,argv); + + EvolutionaryAlgorithm ea(parentPopulationSize,offspringPopulationSize,selectionPressure,replacementPressure, + selectionOperator,replacementOperator,pCrossover, pMutation, pMutationPerGene,outputfile,inputfile); + + StoppingCriterion* sc = new GenerationalCriterion(&ea,setVariable("nbGen",\NB_GEN)); + ea.addStoppingCriterion(sc); + Population* pop = ea.getPopulation(); + + + ea.runEvolutionaryLoop(); + + EASEAFinal(pop); + + delete pop; + delete sc; + delete selectionOperator; + delete replacementOperator; + delete globalRandomGenerator; + + + return 0; +} + + +\START_CUDA_GENOME_CU_TPL +#include "EASEAIndividual.hpp" +#include "EASEAUserClasses.hpp" +#include +#include +#include + +#define STD_TPL + +extern RandomGenerator* globalRandomGenerator; + +\INSERT_USER_DECLARATIONS +\ANALYSE_USER_CLASSES + +\INSERT_USER_FUNCTIONS + +\INSERT_INITIALISATION_FUNCTION +\INSERT_FINALIZATION_FUNCTION +\INSERT_GENERATION_FUNCTION + +void EASEAFinal(Population* pop){ + \INSERT_FINALIZATION_FCT_CALL +} + +void EASEAInit(int argc, char** argv){ + \INSERT_INIT_FCT_CALL +} + + +using namespace std; + +RandomGenerator* Individual::rg; + +Individual::Individual(){ + \GENOME_CTOR + \INSERT_EO_INITIALISER + valid = false; + fitness = 0; +} + + +Individual::~Individual(){ + \GENOME_DTOR +} + + +float Individual::evaluate(){ + if(valid) + return fitness; + else{ + valid = true; + \INSERT_EVALUATOR + } +} + +Individual::Individual(const Individual& genome){ + + // ******************** + // Problem specific part + \COPY_CTOR + + // ******************** + // Generic part + this->valid = genome.valid; + this->fitness = genome.fitness; +} + + +Individual* Individual::crossover(Individual** ps){ + // ******************** + // Generic part + Individual parent1(*this); + Individual parent2(*ps[0]); + Individual child1(*this); + + //DEBUG_PRT("Xover"); +/* cout << "p1 : " << parent1 << endl; */ +/* cout << "p2 : " << parent2 << endl; */ + + // ******************** + // Problem specific part + \INSERT_CROSSOVER + + child1.valid = false; +/* cout << "child1 : " << child1 << endl; */ + return new Individual(child1); +} + + +void Individual::printOn(std::ostream& os) const{ + \INSERT_DISPLAY +} + +std::ostream& operator << (std::ostream& O, const Individual& B) +{ + // ******************** + // Problem specific part + O << "\nIndividual : "<< std::endl; + O << "\t\t\t"; + B.printOn(O); + + if( B.valid ) O << "\t\t\tfitness : " << B.fitness; + else O << "fitness is not yet computed" << std::endl; + return O; +} + + +size_t Individual::mutate( float pMutationPerGene ){ + this->valid=false; + + + // ******************** + // Problem specific part + \INSERT_MUTATOR +} + +/* **************************************** + EvolutionaryAlgorithm class +****************************************/ + +/** + @DEPRECATED This contructor will be deleted. It was for test only, because it + is too much constrained (default selection/replacement operator) + */ +EvolutionaryAlgorithm::EvolutionaryAlgorithm( size_t parentPopulationSize, + size_t offspringPopulationSize, + float selectionPressure, float replacementPressure, + float pCrossover, float pMutation, + float pMutationPerGene){ + RandomGenerator* rg = globalRandomGenerator; + + + SelectionOperator* so = new MaxTournament(rg); + SelectionOperator* ro = new MaxTournament(rg); + + Individual::initRandomGenerator(rg); + Population::initPopulation(so,ro,selectionPressure,replacementPressure); + + this->population = new Population(parentPopulationSize,offspringPopulationSize, + pCrossover,pMutation,pMutationPerGene,rg); + + this->currentGeneration = 0; + + this->reduceParents = 0; + this->reduceOffsprings = 0; + + +} + +EvolutionaryAlgorithm::EvolutionaryAlgorithm( size_t parentPopulationSize, + size_t offspringPopulationSize, + float selectionPressure, float replacementPressure, + SelectionOperator* selectionOperator, SelectionOperator* replacementOperator, + float pCrossover, float pMutation, + float pMutationPerGene, string& outputfile, string& inputfile){ + + RandomGenerator* rg = globalRandomGenerator; + + SelectionOperator* so = selectionOperator; + SelectionOperator* ro = replacementOperator; + + Individual::initRandomGenerator(rg); + Population::initPopulation(so,ro,selectionPressure,replacementPressure); + + this->population = new Population(parentPopulationSize,offspringPopulationSize, + pCrossover,pMutation,pMutationPerGene,rg); + + this->currentGeneration = 0; + + this->reduceParents = 0; + this->reduceOffsprings = 0; + + if( outputfile.length() ) + this->outputfile = new string(outputfile); + else + this->outputfile = NULL; + + if( inputfile.length() ) + this->inputfile = new std::string(inputfile); + else + this->inputfile = NULL; + + + +} + +void EvolutionaryAlgorithm::addStoppingCriterion(StoppingCriterion* sc){ + this->stoppingCriteria.push_back(sc); +} + +void EvolutionaryAlgorithm::runEvolutionaryLoop(){ + std::vector tmpVect; + + + std::cout << "Parent's population initializing "<< std::endl; + this->population->initializeParentPopulation(); + std::cout << *population << std::endl; + + struct timeval begin; + gettimeofday(&begin,NULL); + + while( this->allCriteria() == false ){ + + population->produceOffspringPopulation(); + population->evaluateOffspringPopulation(); + + population->evaluateMoPopulation(); + + if(reduceParents) + population->reduceParentPopulation(reduceParents); + + if(reduceOffsprings) + population->reduceOffspringPopulation(reduceOffsprings); + + population->reduceTotalPopulation(); + + \INSERT_GEN_FCT_CALL + + showPopulationStats(begin); + currentGeneration += 1; + } + population->sortParentPopulation(); + std::cout << "Generation : " << currentGeneration << std::endl; + + +} + + +void EvolutionaryAlgorithm::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; iparentPopulationSize; i++){ + currentAverageFitness+=population->parents[i]->getFitness(); +#if \MINIMAXI + if(population->parents[i]->getFitness()>population->Best->getFitness()) +#else + if(population->parents[i]->getFitness()Best->getFitness()) +#endif + population->Best=population->parents[i]; + } + + currentAverageFitness/=population->parentPopulationSize; + + for(size_t i=0; iparentPopulationSize; i++){ + currentSTDEV+=(population->parents[i]->getFitness()-currentAverageFitness)*(population->parents[i]->getFitness()-currentAverageFitness); + } + currentSTDEV/=population->parentPopulationSize; + currentSTDEV=sqrt(currentSTDEV); + + //Affichage + if(currentGeneration==0) + printf("GEN\tTIME\tEVAL\tBEST\t\tAVG\t\tSTDEV\n\n"); + + + struct timeval end, res; + gettimeofday(&end,0); + timersub(&end,&beginTime,&res); + printf("%lu\t%d.%06d\t%lu\t%f\t%f\t%f\n",currentGeneration,res.tv_sec,res.tv_usec,population->currentEvaluationNb, + population->Best->getFitness(),currentAverageFitness,currentSTDEV); +} + +bool EvolutionaryAlgorithm::allCriteria(){ + + for( size_t i=0 ; ireached() ){ + std::cout << "Stopping criterion reached : " << i << std::endl; + return true; + } + } + return false; +} + + + +\START_CUDA_USER_CLASSES_H_TPL +#include +#include +#include +using namespace std; +\INSERT_USER_CLASSES + +\START_CUDA_GENOME_H_TPL +#ifndef __INDIVIDUAL +#define __INDIVIDUAL +#include "EASEATools.hpp" +#include +#include +#include + + +\INSERT_USER_CLASSES_DEFINITIONS + +void EASEAInit(int argc, char *argv[]); +void EASEAFinal(Population* population); +void EASEAFinalization(Population* population); + +class Individual{ + + public: // in AESAE the genome is public (for user functions,...) + \INSERT_GENOME + bool valid; + float fitness; + float f1,f2; + static RandomGenerator* rg; + + public: + Individual(); + Individual(const Individual& indiv); + virtual ~Individual(); + float evaluate(); + static size_t getCrossoverArrity(){ return 2; } + float getFitness(){ return this->fitness; } + Individual* crossover(Individual** p2); + void printOn(std::ostream& O) const; + + size_t mutate(float pMutationPerGene); + + friend std::ostream& operator << (std::ostream& O, const Individual& B) ; + static void initRandomGenerator(RandomGenerator* rg){ Individual::rg = rg;} + + private: + friend class boost::serialization::access; + template void serialize(Archive& ar, const unsigned int version){ + + ar & fitness; + DEBUG_PRT("(de)serialization of %f fitness",fitness); + ar & valid; + DEBUG_PRT("(de)serialization of %d valid",valid); + \GENOME_SERIAL + } + + +}; + + +/* **************************************** + EvolutionaryAlgorithm class +****************************************/ +class EvolutionaryAlgorithm{ +public: + EvolutionaryAlgorithm( size_t parentPopulationSize, size_t offspringPopulationSize, + float selectionPressure, float replacementPressure, + float pCrossover, float pMutation, float pMutationPerGene); + EvolutionaryAlgorithm( size_t parentPopulationSize,size_t offspringPopulationSize, + float selectionPressure, float replacementPressure, + SelectionOperator* selectionOperator, SelectionOperator* replacementOperator, + float pCrossover, float pMutation, + float pMutationPerGene, std::string& outputfile, std::string& inputfile); + + size_t* getCurrentGenerationPtr(){ return ¤tGeneration;} + void addStoppingCriterion(StoppingCriterion* sc); + void runEvolutionaryLoop(); + bool allCriteria(); + Population* getPopulation(){ return population;} + size_t getCurrentGeneration() { return currentGeneration;} +public: + size_t currentGeneration; + Population* population; + size_t reduceParents; + size_t reduceOffsprings; + //void showPopulationStats(); + void showPopulationStats(struct timeval beginTime); + + + std::vector stoppingCriteria; + + std::string* outputfile; + std::string* inputfile; +}; + + +#endif + + +\START_CUDA_TOOLS_CPP_TPL/* **************************************** + + RandomGenerator class + +****************************************/ +#include "EASEATools.hpp" +#include "EASEAIndividual.hpp" +#include +#include +#include +#include +#include +#include +#include + + +RandomGenerator::RandomGenerator(unsigned int seed){ + srand(seed); +} + +int RandomGenerator::randInt(){ + return rand(); +} + +bool RandomGenerator::tossCoin(){ + + int rVal = rand(); + if( rVal >=(RAND_MAX/2)) + return true; + else return false; +} + + +bool RandomGenerator::tossCoin(float bias){ + + int rVal = rand(); + if( rVal <=(RAND_MAX*bias) ) + return true; + else return false; +} + + + +int RandomGenerator::randInt(int min, int max){ + + int rValue = (((float)rand()/RAND_MAX))*(max-min); + //DEBUG_PRT("Int Random Value : %d",min+rValue); + return rValue+min; + +} + +int RandomGenerator::random(int min, int max){ + return randInt(min,max); +} + +float RandomGenerator::randFloat(float min, float max){ + float rValue = (((float)rand()/RAND_MAX))*(max-min); + //DEBUG_PRT("Float Random Value : %f",min+rValue); + return rValue+min; +} + +float RandomGenerator::random(float min, float max){ + return randFloat(min,max); +} + +double RandomGenerator::random(double min, double max){ + return randFloat(min,max); +} + + +int RandomGenerator::getRandomIntMax(int max){ + double r = rand(); + r = r / RAND_MAX; + r = r * max; + return r; +} + + +/* **************************************** + Tournament class (min and max) +****************************************/ +void MaxTournament::initialize(Individual** population, float selectionPressure, size_t populationSize) { + SelectionOperator::initialize(population,selectionPressure,populationSize); +} + + +float MaxTournament::getExtremum(){ + return -FLT_MAX; +} + +size_t MaxTournament::selectNext(size_t populationSize){ + size_t bestIndex = 0; + float bestFitness = -FLT_MAX; + + //std::cout << "MaxTournament selection " ; + if( currentSelectionPressure >= 2 ){ + for( size_t i = 0 ; igetRandomIntMax(populationSize); + //std::cout << selectedIndex << " "; + float currentFitness = population[selectedIndex]->getFitness(); + + if( bestFitness < currentFitness ){ + bestIndex = selectedIndex; + bestFitness = currentFitness; + } + + } + } + else if( currentSelectionPressure <= 1 && currentSelectionPressure > 0 ){ + size_t i1 = rg->getRandomIntMax(populationSize); + size_t i2 = rg->getRandomIntMax(populationSize); + + if( rg->tossCoin(currentSelectionPressure) ){ + if( population[i1]->getFitness() > population[i2]->getFitness() ){ + bestIndex = i1; + } + } + else{ + if( population[i1]->getFitness() > population[i2]->getFitness() ){ + bestIndex = i2; + } + } + } + else{ + std::cerr << " MaxTournament selection operator doesn't handle selection pressure : " + << currentSelectionPressure << std::endl; + } + //std::cout << std::endl; + return bestIndex; +} + + +void MinTournament::initialize(Individual** population, float selectionPressure, size_t populationSize) { + SelectionOperator::initialize(population,selectionPressure,populationSize); +} + +float MinTournament::getExtremum(){ + return FLT_MAX; +} + + +size_t MinTournament::selectNext(size_t populationSize){ + size_t bestIndex = 0; + float bestFitness = FLT_MAX; + + //std::cout << "MinTournament selection " ; + if( currentSelectionPressure >= 2 ){ + for( size_t i = 0 ; igetRandomIntMax(populationSize); + //std::cout << selectedIndex << " "; + float currentFitness = population[selectedIndex]->getFitness(); + + if( bestFitness > currentFitness ){ + bestIndex = selectedIndex; + bestFitness = currentFitness; + } + + } + } + else if( currentSelectionPressure <= 1 && currentSelectionPressure > 0 ){ + size_t i1 = rg->getRandomIntMax(populationSize); + size_t i2 = rg->getRandomIntMax(populationSize); + + if( rg->tossCoin(currentSelectionPressure) ){ + if( population[i1]->getFitness() < population[i2]->getFitness() ){ + bestIndex = i1; + } + } + else{ + if( population[i1]->getFitness() < population[i2]->getFitness() ){ + bestIndex = i2; + } + } + } + else{ + std::cerr << " MinTournament selection operator doesn't handle selection pressure : " + << currentSelectionPressure << std::endl; + } + + //std::cout << std::endl; + return bestIndex; +} + + +/* **************************************** + SelectionOperator class +****************************************/ +void SelectionOperator::initialize(Individual** population, float selectionPressure, size_t populationSize){ + this->population = population; + this->currentSelectionPressure = selectionPressure; +} + +size_t SelectionOperator::selectNext(size_t populationSize){ return 0; } + + +/* **************************************** + GenerationalCriterion class +****************************************/ +GenerationalCriterion::GenerationalCriterion(EvolutionaryAlgorithm* ea, size_t generationalLimit){ + this->currentGenerationPtr = ea->getCurrentGenerationPtr(); + this->generationalLimit = generationalLimit; +} + +bool GenerationalCriterion::reached(){ + if( generationalLimit <= *currentGenerationPtr ){ + std::cout << "Current generation " << *currentGenerationPtr << " Generational limit : " << + generationalLimit << std::endl; + return true; + } + else return false; +} + + +/* **************************************** + Population class +****************************************/ +SelectionOperator* Population::selectionOperator; +SelectionOperator* Population::replacementOperator; + +float Population::selectionPressure; +float Population::replacementPressure; + + +Population::Population(){ +} + +Population::Population(size_t parentPopulationSize, size_t offspringPopulationSize, + float pCrossover, float pMutation, float pMutationPerGene, + RandomGenerator* rg){ + + this->parents = new Individual*[parentPopulationSize]; + this->offsprings = new Individual*[offspringPopulationSize]; + + this->parentPopulationSize = parentPopulationSize; + this->offspringPopulationSize = offspringPopulationSize; + + this->actualParentPopulationSize = 0; + this->actualOffspringPopulationSize = 0; + + this->pCrossover = pCrossover; + this->pMutation = pMutation; + this->pMutationPerGene = pMutationPerGene; + + this->rg = rg; + + this->currentEvaluationNb = 0; +} + +void Population::syncInVector(){ + for( size_t i = 0 ; iparents); + delete[](this->offsprings); +} + +void Population::initPopulation(SelectionOperator* selectionOperator, + SelectionOperator* replacementOperator, + float selectionPressure, float replacementPressure){ + Population::selectionOperator = selectionOperator; + Population::replacementOperator = replacementOperator; + Population::selectionPressure = selectionPressure; + Population::replacementPressure = replacementPressure; +} + + +void Population::initializeParentPopulation(){ + + DEBUG_PRT("Creation of %d/%d parents (other could have been loaded from input file)",parentPopulationSize-actualParentPopulationSize,parentPopulationSize); + for( size_t i=actualParentPopulationSize ; ievaluate(); + currentEvaluationNb += populationSize; +} + + +void Population::evaluateParentPopulation(){ + evaluatePopulation(parents,parentPopulationSize); +} + + +void Population::evaluateOffspringPopulation(){ + evaluatePopulation(offsprings,offspringPopulationSize); +} + +/** + Strong dominance + */ +int check_dominance(Individual* i1 , Individual* i2){ + + bool flag1=0,flag2=0; + + if( i1->f1 < i2->f1 ) + flag1 = 1; + else + if( i1->f1 > i2->f1 ) + flag2 = 1; + + if( i1->f2 < i2->f2 ) + flag1 = 1; + else + if( i1->f2 > i2->f2 ) + flag2 = 1; + + + + if( flag1 == 1 && flag2 == 0 ) + return 1; + else + if( flag1 == 0 && flag2 == 1) + return -1; + return 0; +} + + + +struct Individual_list{ + Individual* content; + struct Individual_list* next; + struct Individual_list* prev; +}; + + +/* struct Individual_list* new_Individual_list(Individual** population, unsigned int size){ */ +/* struct Individual_list* head = NULL; */ + +/* for( unsigned int i=0 ; inext = head; */ +/* tmp->content = population[i]; */ +/* tmp->prev = NULL; */ +/* if(head) head->prev = tmp; */ +/* head = tmp; */ +/* } */ +/* return head; */ +/* } */ + +struct Individual_list* new_Individual_list_reverse(Individual** population, unsigned int size){ + struct Individual_list* head = NULL; + + for( int i=(size-1) ; i>=0 ; i--){ + struct Individual_list* tmp=(struct Individual_list*)malloc(sizeof(struct Individual_list)); + tmp->next = head; + tmp->content = population[i]; + tmp->prev = NULL; + if(head) head->prev = tmp; + head = tmp; + } + return head; +} + + +void show_Individual_list_content(struct Individual_list* head){ + std::cout << "Printing list" << std::endl; + unsigned int ctr = 0; + while(head!=NULL){ + std::cout << *head->content << "\t\t current : " << head << " next : " << head->next << " prev : " << head->prev ; + head = head->next; + ctr++; + } + std::cout << "\nEnd of list : "<< ctr << std::endl; +} + + +struct Individual_list* Individual_list_get(struct Individual_list* head, unsigned int){ + for( struct Individual_list* h1=head ; h1!=NULL ; h1=h1->next){ + return h1; + } + return NULL; +} + + + +/** + remove an element (current) from a list (head) + if list become empty, it is freed and become head become null + */ +void Individual_list_remove(struct Individual_list** head, struct Individual_list* current){ + struct Individual_list* tmp = current; + + if(*head==current){ + if(current->next){ + *head = (*head)->next; + (*head)->prev = NULL; + } + else{ + // if this element is the last from the list + free(tmp); + *head=NULL; + return ; + } + } + else{ + current->prev->next = current->next; + current->next->prev = current->prev; + } + free(tmp); +} + +void Population::evaluateMoPopulation(){ + size_t actualGlobalSize = actualParentPopulationSize+actualOffspringPopulationSize; + Individual** globalPopulation = new Individual*[actualGlobalSize](); + + unsigned int rank = 1; + + memcpy(globalPopulation,parents,sizeof(Individual*)*actualParentPopulationSize); + memcpy(globalPopulation+actualParentPopulationSize,offsprings,sizeof(Individual*)*actualOffspringPopulationSize); + + struct Individual_list* head = new_Individual_list_reverse(globalPopulation,actualGlobalSize); + + delete[](globalPopulation); + + struct Individual_list* h1,* h2; + int** dom = new int*[actualGlobalSize](); + for( unsigned int i=0 ; i pareto_front; + + while(head!=NULL){ + unsigned int i=0,j=0; + for( h1=head ; h1!=NULL ; h1=h1->next,i++){ + j=0; + for( h2=head ; h2!=NULL ; h2=h2->next,j++){ + dom[i][j] = check_dominance(h1->content,h2->content); + } + + } + + int flag; + unsigned int non_dominated_ctr = 0; + + for( unsigned int i=0 ; if1 << " f2 : " << globalPopulation[i]->f2 <content->fitness = rank; + pareto_front.push_back(non_dominated_individual->content); + Individual_list_remove(&head,non_dominated_individual); + non_dominated_ctr++; + //Individual_list_remove(&head, + } + } + + //for( unsigned int i=0 ; iinitialize(population,replacementPressure,populationSize); + + for( size_t i=0 ; iselectNext(populationSize - i); + // std::cout << "Selected " << selectedIndex << "/" << populationSize + // << " replaced by : " << populationSize-(i+1)<< std::endl; + reducedPopulation[i] = population[selectedIndex]; + + // erase it to the std population by swapping last individual end current + population[selectedIndex] = population[populationSize-(i+1)]; + //population[populationSize-(i+1)] = NULL; + } + + //return reducedPopulation; +} + + +Individual** Population::reduceParentPopulation(size_t obSize){ + Individual** nextGeneration = new Individual*[obSize]; + + reducePopulation(parents,actualParentPopulationSize,nextGeneration,obSize, + Population::replacementOperator); + + // free no longer needed individuals + for( size_t i=0 ; iactualParentPopulationSize = obSize; + parents = nextGeneration; + + + return nextGeneration; +} + + +Individual** Population::reduceOffspringPopulation(size_t obSize){ + Individual** nextGeneration = new Individual*[obSize]; + + reducePopulation(offsprings,actualOffspringPopulationSize,nextGeneration,obSize, + Population::replacementOperator); + + // free no longer needed individuals + for( size_t i=0 ; iactualParentPopulationSize = obSize; + parents = nextGeneration; + return nextGeneration; +} + + +static int individualCompare(const void* p1, const void* p2){ + Individual** p1_i = (Individual**)p1; + Individual** p2_i = (Individual**)p2; + + return p1_i[0]->getFitness() > p2_i[0]->getFitness(); +} + +static int individualRCompare(const void* p1, const void* p2){ + Individual** p1_i = (Individual**)p1; + Individual** p2_i = (Individual**)p2; + + return p1_i[0]->getFitness() < p2_i[0]->getFitness(); +} + + +void Population::sortPopulation(Individual** population, size_t populationSize){ + qsort(population,populationSize,sizeof(Individual*),individualCompare); +} + +void Population::sortRPopulation(Individual** population, size_t populationSize){ + qsort(population,populationSize,sizeof(Individual*),individualRCompare); +} + + +/** + Reduit les populations en faisant l'operation de remplacement. + + @TODO : on aurait voulu eviter la recopie des deux populations en une seule + mais cela semble incompatible avec SelectionOperator (notamment l'operation + d'initialisation. +*/ +void Population::reduceTotalPopulation(){ + + Individual** nextGeneration = new Individual*[parentPopulationSize]; + +#if ((\ELITE_SIZE!=0) && (\ELITISM==true)) // If there is elitism and it is strong + Population::elitism(\ELITE_SIZE,parents,actualParentPopulationSize, + nextGeneration,parentPopulationSize); // do the elitism on the parent population only + actualParentPopulationSize -= \ELITE_SIZE; // decrement the parent population size +#endif + + size_t actualGlobalSize = actualParentPopulationSize+actualOffspringPopulationSize; + Individual** globalPopulation = new Individual*[actualGlobalSize](); + + + memcpy(globalPopulation,parents,sizeof(Individual*)*actualParentPopulationSize); + memcpy(globalPopulation+actualParentPopulationSize,offsprings, + sizeof(Individual*)*actualOffspringPopulationSize); + replacementOperator->initialize(globalPopulation, replacementPressure,actualGlobalSize); + +#if ((\ELITE_SIZE!=0) && (\ELITISM==false)) // If there is elitism and it is weak + Population::elitism(\ELITE_SIZE,globalPopulation,actualGlobalSize, + nextGeneration,parentPopulationSize); // do the elitism on the global (already merged) population + actualGlobalSize -= \ELITE_SIZE; // decrement the parent population size +#endif + + + Population::reducePopulation(globalPopulation,actualGlobalSize,\ELITE_SIZE+nextGeneration, + parentPopulationSize-\ELITE_SIZE,replacementOperator); + + for( size_t i=0 ; iinitialize(parents,selectionPressure,actualParentPopulationSize); + + for( size_t i=0 ; iselectNext(parentPopulationSize); + p1 = parents[index]; + + if( rg->tossCoin(pCrossover) ){ + for( size_t j=0 ; jselectNext(parentPopulationSize); + ps[j] = parents[index]; + } + child = p1->crossover(ps); + } + else child = new Individual(*parents[index]); + + if( rg->tossCoin(pMutation) ){ + child->mutate(pMutationPerGene); + } + + offsprings[actualOffspringPopulationSize++] = child; + } + delete[](ps); + } + + + + +/** + Here we save elit individuals to the replacement + + @ARG elitismSize the number of individuals save by elitism + @ARG population the population where the individuals are save + @ARG populationSize the size of the population + @ARG outPopulation the output population, this must be allocated with size greather than elitism + @ARG outPopulationSize the size of the output population + +*/ +void Population::elitism(size_t elitismSize, Individual** population, size_t populationSize, + Individual** outPopulation, size_t outPopulationSize){ + + float bestFitness = population[0]->getFitness(); + size_t bestIndividual = 0; + + if( elitismSize >= 5 )DEBUG_PRT("Warning, elitism has O(n) complexity, elitismSize is maybe too big (%d)",elitismSize); + + + for(size_t i = 0 ; igetExtremum(); + bestIndividual = 0; + for( size_t j=0 ; jgetFitness() ){ +#else + if( bestFitness > population[j]->getFitness() ){ +#endif + bestFitness = population[j]->getFitness(); + bestIndividual = j; + } + } + outPopulation[i] = population[bestIndividual]; + population[bestIndividual] = population[populationSize-(i+1)]; + population[populationSize-(i+1)] = NULL; + } +} + + + + +std::ostream& operator << (std::ostream& O, const Population& B) +{ + + size_t offspringPopulationSize = B.offspringPopulationSize; + size_t realOffspringPopulationSize = B.actualOffspringPopulationSize; + + size_t parentPopulationSize = B.parentPopulationSize; + size_t realParentPopulationSize = B.actualParentPopulationSize; + + + O << "Population : "<< std::endl; + O << "\t Parents size : "<< realParentPopulationSize << "/" << + parentPopulationSize << std::endl; + + for( size_t i=0 ; irandom(0,populationSize-1); +} + +float MaxRandom::getExtremum(){ + return -FLT_MAX; +} + +MinRandom::MinRandom(RandomGenerator* globalRandomGenerator){ + rg = globalRandomGenerator; +} + +void MinRandom::initialize(Individual** population, float selectionPressure, size_t populationSize){ + SelectionOperator::initialize(population,selectionPressure,populationSize); +} + +size_t MinRandom::selectNext(size_t populationSize){ + return rg->random(0,populationSize-1); +} + +float MinRandom::getExtremum(){ + return -FLT_MAX; +} + +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(); + cout << argumentName << " is declared in user command line as "<< ret << endl; + } + else if( vm_file.count(argumentName) ){ + ret = vm_file[argumentName].as(); + 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(); + cout << argumentName << " is declared in user command line as "<< ret << endl; + } + else if( vm_file.count(argumentName) ){ + ret = vm_file[argumentName].as(); + 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 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 : " <(), "set compression level") + ("seed", po::value(), "set the global seed of the pseudo random generator") + ("popSize",po::value(),"set the population size") + ("nbOffspring",po::value(),"set the offspring population size") + ("elite",po::value(),"Nb of elite parents (absolute)") + ("eliteType",po::value(),"Strong (1) or weak (1)") + ("nbGen",po::value(),"Set the number of generation") + ("surviveParents",po::value()," Nb of surviving parents (absolute)") + ("surviveOffsprings",po::value()," Nb of surviving offsprings (absolute)") + ("outputfile",po::value(),"Set an output file for the final population (default : none)") + ("inputfile",po::value(),"Set an input file for the initial population (default : none)") + ("u1",po::value(),"User defined parameter 1") + ("u2",po::value(),"User defined parameter 2") + ("u3",po::value(),"User defined parameter 3") + ("u4",po::value(),"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 +#include +#include +#include //for serialization (dumping) +#include //for serialization (loading) +#include + +class EvolutionaryAlgorithm; +class Individual; +class Population; + +#ifdef DEBUG +#define DEBUG_PRT(format, args...) fprintf (stdout,"***DBG*** %s-%d: "format"\n",__FILE__,__LINE__,##args) +#define DEBUG_YACC(format, args...) fprintf (stdout,"***DBG_YACC*** %s-%d: "format"\n",__FILE__,__LINE__,##args) +#else +#define DEBUG_PRT(format, args...) +#define DEBUG_YACC(format, args...) +#endif + + +/* **************************************** + StoppingCriterion class +****************************************/ +#ifndef __EASEATOOLS +#define __EASEATOOLS +class StoppingCriterion { + +public: + virtual bool reached() = 0; + +}; + + +/* **************************************** + GenerationalCriterion class +****************************************/ +class GenerationalCriterion : public StoppingCriterion { + private: + size_t* currentGenerationPtr; + size_t generationalLimit; + public: + virtual bool reached(); + GenerationalCriterion(EvolutionaryAlgorithm* ea, size_t generationalLimit); + +}; + + +/* **************************************** + RandomGenerator class +****************************************/ +class RandomGenerator{ +public: + RandomGenerator(unsigned int seed); + int randInt(); + bool tossCoin(); + bool tossCoin(float bias); + int randInt(int min, int max); + int getRandomIntMax(int max); + float randFloat(float min, float max); + int random(int min, int max); + float random(float min, float max); + double random(double min, double max); + +}; + + + +/* **************************************** + Selection Operator class +****************************************/ +class SelectionOperator{ +public: + virtual void initialize(Individual** population, float selectionPressure, size_t populationSize); + virtual size_t selectNext(size_t populationSize); + virtual float getExtremum() = 0 ; +protected: + Individual** population; + float currentSelectionPressure; +}; + + +/* **************************************** + Tournament classes (min and max) +****************************************/ +class MaxTournament : public SelectionOperator{ +public: + MaxTournament(RandomGenerator* rg){ this->rg = rg; } + virtual void initialize(Individual** population, float selectionPressure, size_t populationSize); + virtual size_t selectNext(size_t populationSize); + float getExtremum(); +private: + RandomGenerator* rg; + +}; + + + +class MinTournament : public SelectionOperator{ +public: + MinTournament(RandomGenerator* rg){ this->rg = rg; } + virtual void initialize(Individual** population, float selectionPressure, size_t populationSize); + virtual size_t selectNext(size_t populationSize); + float getExtremum(); +private: + RandomGenerator* rg; + +}; + + +class MaxDeterministic : public SelectionOperator{ + public: + virtual void initialize(Individual** population, float selectionPressure, size_t populationSize); + virtual size_t selectNext(size_t populationSize); + float getExtremum(); + private: + size_t populationSize; +}; + +class MinDeterministic : public SelectionOperator{ + public: + virtual void initialize(Individual** population, float selectionPressure, size_t populationSize); + virtual size_t selectNext(size_t populationSize); + float getExtremum(); + private: + size_t populationSize; + +}; + + +class MaxRandom : public SelectionOperator{ + public: + MaxRandom(RandomGenerator* globalRandomGenerator); + virtual void initialize(Individual** population, float selectionPressure, size_t populationSize); + virtual size_t selectNext(size_t populationSize); + float getExtremum(); + private: + size_t populationSize; + RandomGenerator* rg; + +}; + +class MinRandom : public SelectionOperator{ + public: + MinRandom(RandomGenerator* globalRandomGenerator); + virtual void initialize(Individual** population, float selectionPressure, size_t populationSize); + virtual size_t selectNext(size_t populationSize); + float getExtremum(); + private: + size_t populationSize; + RandomGenerator* rg; +}; + + + +class Population { + + public: + + float pCrossover; + float pMutation; + float pMutationPerGene; + + Individual* Best; + + Individual** parents; + Individual** offsprings; + + size_t parentPopulationSize; + size_t offspringPopulationSize; + + size_t actualParentPopulationSize; + size_t actualOffspringPopulationSize; + + static SelectionOperator* selectionOperator; + static SelectionOperator* replacementOperator; + + size_t currentEvaluationNb; + RandomGenerator* rg; + std::vector pop_vect; + + public: + Population(); + Population(size_t parentPopulationSize, size_t offspringPopulationSize, + float pCrossover, float pMutation, float pMutationPerGene, RandomGenerator* rg); + virtual ~Population(); + + void initializeParentPopulation(); + void evaluatePopulation(Individual** population, size_t populationSize); + void evaluateParentPopulation(); + void evaluateMoPopulation(); + + + static void elitism(size_t elitismSize, Individual** population, size_t populationSize, Individual** outPopulation, + size_t outPopulationSize); + + void evaluateOffspringPopulation(); + Individual** reducePopulations(Individual** population, size_t populationSize, + Individual** reducedPopulation, size_t obSize); + Individual** reduceParentPopulation(size_t obSize); + Individual** reduceOffspringPopulation(size_t obSize); + void reduceTotalPopulation(); + void evolve(); + + static float selectionPressure; + static float replacementPressure; + static void initPopulation(SelectionOperator* selectionOperator, + SelectionOperator* replacementOperator, + float selectionPressure, float replacementPressure); + + static void sortPopulation(Individual** population, size_t populationSize); + + static void sortRPopulation(Individual** population, size_t populationSize); + + + void sortParentPopulation(){ Population::sortPopulation(parents,actualParentPopulationSize);} + + void produceOffspringPopulation(); + + friend std::ostream& operator << (std::ostream& O, const Population& B); + + + void setParentPopulation(Individual** population, size_t actualParentPopulationSize){ + this->parents = population; + this->actualParentPopulationSize = actualParentPopulationSize; + } + + static void reducePopulation(Individual** population, size_t populationSize, + Individual** reducedPopulation, size_t obSize, + SelectionOperator* replacementOperator); + void syncOutVector(); + void syncInVector(); + + private: + friend class boost::serialization::access; + template void serialize(Archive& ar, const unsigned int version){ + + ar & actualParentPopulationSize; + DEBUG_PRT("(de)serialization of %d parents",actualParentPopulationSize); + ar & pop_vect; + DEBUG_PRT("(de)serialization of %d offspring",actualOffspringPopulationSize); + } +}; + +/* namespace boost{ */ +/* namespace serialization{ */ +/* template */ +/* void serialize(Archive & ar,std::vector population, const unsigned int version){ */ +/* ar & population; */ +/* } */ +/* } */ +/* } */ + +void parseArguments(const char* parametersFileName, int ac, char** av); +int setVariable(const std::string optionName, int defaultValue); +std::string setVariable(const std::string optionName, std::string defaultValue); + + + +#endif + + + +\START_CUDA_MAKEFILE_TPL + +NVCC= nvcc +CPPC= g++ +CXXFLAGS+=-g -Wall +LDFLAGS=-lboost_program_options -lboost_serialization + +#USER MAKEFILE OPTIONS : +\INSERT_MAKEFILE_OPTION#END OF USER MAKEFILE OPTIONS + +EASEA_SRC= EASEATools.cpp EASEAIndividual.cpp +EASEA_MAIN_HDR= EASEA.cpp +EASEA_UC_HDR= EASEAUserClasses.hpp + +EASEA_HDR= $(EASEA_SRC:.cpp=.hpp) + +SRC= $(EASEA_SRC) $(EASEA_MAIN_HDR) +HDR= $(EASEA_HDR) $(EASEA_UC_HDR) +OBJ= $(EASEA_SRC:.cpp=.o) $(EASEA_MAIN_HDR:.cpp=.o) + +BIN= EASEA + +all:$(BIN) + +$(BIN):$(OBJ) + $(CXX) $^ -o $@ $(LDFLAGS) + +easeaclean: clean + rm -f Makefile $(SRC) $(HDR) EASEA.mak +clean: + rm -f $(OBJ) $(BIN) + +\START_EO_PARAM_TPL#**************************************** +# +# EASEA.prm +# +# Parameter file generated by AESAE-EO v0.7b +# +#*************************************** +# --seed=0 # -S : Random number seed. It is possible to give a specific seed. + +###### Evolution Engine ###### +--popSize=\POP_SIZE # -P : Population Size +--nbOffspring=\OFF_SIZE # -O : Nb of offspring (percentage or absolute) + +###### Evolution Engine / Replacement ###### +--elite=\ELITE_SIZE # Nb of elite parents (percentage or absolute) +--eliteType=\ELITISM # Strong (true) or weak (false) elitism (set elite to 0 for none) +--surviveParents=\SURV_PAR_SIZE # Nb of surviving parents (percentage or absolute) +# --reduceParents=Ranking # Parents reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform +--surviveOffspring=\SURV_OFF_SIZE # Nb of surviving offspring (percentage or absolute) +# --reduceOffspring=Roulette # Offspring reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform +# --reduceFinal=DetTour(2) # Final reducer: Deterministic, EP(T), DetTour(T), StochTour(t), Uniform + + +\TEMPLATE_END -- GitLab