📄 ex27.c
字号:
/* ---------------------------------------------------------------------------- ex27.C mbwall 24mar96 Copyright (c) 1995-1996 Massachusetts Institute of Technology The code for this example is adapted from an original implementation by Thomas Grueninger (from Uni Stuttgart, visiting scholar at MIT) DESCRIPTION: This example shows how to use the Deterministic Crowding genetic algorithm.You can specify one of 4 different functions (they are described in more detaillater in this file). (This code was originally used with a 3D OpenGL-based program to illustratethe differences in convergence between various speciation methods. Believe me,it looks much better running in real-time in 3D, but, alas, there is not yetany standard 3D cross-platform API, so you get this instead.)---------------------------------------------------------------------------- */#include <math.h>#include <ga/GASStateGA.h>#include <ga/GAList.h>#include <ga/GA1DArrayGenome.h>// If your compiler does not do automatic instantiation (e.g. g++ 2.6.8),// then define the NO_AUTO_INST directive.#ifdef NO_AUTO_INST#include <ga/GAList.C>#include <ga/GA1DArrayGenome.C>#if defined(__GNUG__)template class GAList<int>;template class GA1DArrayGenome<float>;#elseGAList<int>;GA1DArrayGenome<float>;#endif#endif// This is the class definition for the deterministic crowding genetic // algorithm. It is based upon the steady-state genetic algorithm, but we// modify the replacement so that it does deterministic crowding as described// by Goldberg (not in his book) and his students.class DCrowdingGA : public GASteadyStateGA {public: GADefineIdentity("DeterministicCrowdingGA", 241); DCrowdingGA(const GAGenome& g) : GASteadyStateGA(g) {} virtual ~DCrowdingGA() {} virtual void step(); DCrowdingGA & operator++() { step(); return *this; }};voidDCrowdingGA::step() { int i,*ip; float d1,d2; GAGenome *mom, *dad; GAList<int> IndPool; while (IndPool.head()) IndPool.destroy(); for (i=0; i<pop->size(); i++) IndPool.insert(i); do { //select mom IndPool.warp(GARandomInt(0,IndPool.size()-1)); ip=IndPool.remove(); mom = &pop->individual(*ip); delete ip; //select dad IndPool.warp(GARandomInt(0,IndPool.size()-1)); ip=IndPool.remove(); dad = &pop->individual(*ip); delete ip; //create child stats.numsel += 2; stats.numcro += (*(mom->sexual()))(*mom, *dad, &tmpPop->individual(0), 0); stats.nummut += tmpPop->individual(0).mutate(pMutation()); stats.numeval += 1; //replace closest parent d1 = tmpPop->individual(0).compare(*mom); d2 = tmpPop->individual(0).compare(*dad); if (d1 < d2) { if (minmax == MINIMIZE) { if (tmpPop->individual(0).score() < mom->score()) { mom->copy(tmpPop->individual(0)); stats.numrep += 1; } } else { if (tmpPop->individual(0).score() > mom->score()) { mom->copy(tmpPop->individual(0)); stats.numrep += 1; } } } else { if (minmax == MINIMIZE) { if (tmpPop->individual(0).score() < dad->score()) { dad->copy(tmpPop->individual(0)); stats.numrep += 1; } } else { if (tmpPop->individual(0).score() > dad->score()) { dad->copy(tmpPop->individual(0)); stats.numrep += 1; } } } } while (IndPool.size()>1); pop->evaluate(gaTrue); stats.update(*pop); }// Set up the various 2-dimensional, real number functions that we will use.typedef float (*Function)(float, float);float Function1(float, float);float Function2(float, float);float Function3(float, float);float Function4(float, float);float ai[25],bi[25];static int which = 0;static Function obj[] = { Function1, Function2, Function3, Function4 };static float minx[] = {-6, -60, -500, -10 };static float maxx[] = { 6, 60, 500, 10 };static float miny[] = {-6, -60, -500, -10 };static float maxy[] = { 6, 60, 500, 10 };// These are the declarations for our genome operators (we do not use the// defaults from GAlib for this example).float Objective(GAGenome&);int Mutator(GAGenome&, float);void Initializer(GAGenome&);int Crossover(const GAGenome&, const GAGenome&, GAGenome*, GAGenome*);float Comparator(const GAGenome&, const GAGenome&);intmain(int argc, char** argv) { cout << "Example 27\n\n"; cout << "Deterministic crowding demonstration program.\n\n"; cout << "In addition to the standard GAlib command-line arguments,\n"; cout << "you can specify one of the four following functions:\n"; cout << " 0 - modified Himmelblau's function\n"; cout << " 1 - Foxholes (25)\n"; cout << " 2 - Schwefel's nasty (1 glob. Max bei (420.96/420.96)\n"; cout << " 3 - Mexican Hat (optimum at 0,0)\n"; cout << endl; int i;// See if we've been given a seed to use (for testing purposes). When you// specify a random seed, the evolution will be exactly the same each time// you use that seed number. for(i=1; i<argc; i++) { if(strcmp(argv[i++],"seed") == 0) GARandomSeed((unsigned int)atoi(argv[i])); } for (i=0; i<25; i++) { ai[i] = 16 * ((i % 5) -2); bi[i] = 16 * ((i / 5) -2); } GA1DArrayGenome<float> genome(2, Objective); genome.initializer(::Initializer); genome.mutator(::Mutator); genome.comparator(::Comparator); genome.crossover(::Crossover); DCrowdingGA ga(genome); ga.maximize(); ga.populationSize(100); ga.nGenerations(100); ga.pMutation(0.05); ga.pCrossover(1.0); ga.selectScores(GAStatistics::AllScores); ga.parameters(argc, argv, gaFalse); for (i=1; i<argc; i++){ if(strcmp("func", argv[i]) == 0 || strcmp("f", argv[i]) == 0){ if(++i >= argc){ cerr << argv[0] << ": the function option needs a number.\n"; exit(1); } else{ which = atoi(argv[i]); continue; } } else if(strcmp("seed", argv[i]) == 0){ if(++i < argc) continue; continue; } else { cerr << argv[0] << ": unrecognized arguement: " << argv[i] << "\n\n"; cerr << "valid arguments include standard GAlib arguments plus:\n"; cerr << " f\tfunction to use (" << which << ")\n"; cerr << "\n"; exit(1); } } ga.evolve(); cout << "best individual is " << ga.statistics().bestIndividual() << "\n\n"; cout << ga.statistics() << "\n"; return 0;}/*****************************************************************************//* Type: 2D FUNCTION *//* Name: Objective2D_1 *//* Description: 2D tooth *//* Boundaries: -6 < x < 6 *//* -6 < y < 6 *//* Source: modified Himmelblau's function from Deb, K. *//* 'GA in multimodal function optimazation' Masters thesis *//* TCGA Rep. 89002 / U. of Alabama *//*****************************************************************************/floatFunction1(float x, float y) { float z = -((x*x+y-11)*(x*x+y-11)+(x+y*y-7)*(x+y*y-7))/200 + 10; return z;}/*****************************************************************************//* Type: 2D FUNCTION *//* Name: Objective2D_2 *//* Description: Foxholes (25) *//* Boundaries: -60 < x < 60 *//* -60 < y < 60 *//* Source: Shekel's Foxholes problem from De Jong's Diss.(1975) *//* 'GA in multimodal function optimazation' Masters thesis *//* TCGA Rep. 89002 / U. of Alabama *//*****************************************************************************/floatFunction2(float x, float y) { int i; float sum = 0; for (i=0; i<25; i++) { sum += (1 / (1 + i + pow((x-ai[i]),6) + pow((y-bi[i]),6))); } float z = 100.0 - (1 / (0.02 + sum)); return z;}/*****************************************************************************//* Type: 2D FUNCTION *//* Name: Objective2D_3 *//* Description: Schwefel's nasty (1 glob. Max bei (420.96/420.96) *//* Boundaries: -500 < x < 500 *//* -500 < y < 500 *//* Source: Schwefel's function in Schoeneburg *//*****************************************************************************/floatFunction3(float x, float y) { float z = fabs(x) * sin(sqrt(fabs(x))) + fabs(y) * sin(sqrt(fabs(y))); //float z = 100 * ( sin(sqrt(fabs(x))) * sin(sqrt(fabs(y))) ); return (z);}/*****************************************************************************//* Type: 2D FUNCTION *//* Name: Objective2D_4 *//* Description: Mexican Hat *//* Boundaries: -10 < x < 10 *//* -10 < y < 10 *//* Source: *//*****************************************************************************/floatFunction4(float x, float y) { float z = sin(sqrt(x*x + y*y))*sin(sqrt(x*x + y*y)) - 0.5; z /= ((1.0 + 0.001*(x*x + y*y))*(1.0 + 0.001*(x*x + y*y))); z = (0.5 - z); return (z);}// These are the operators that we'll use for the real number genome.floatObjective(GAGenome& g) { GA1DArrayGenome<float>& genome = (GA1DArrayGenome<float>&)g; return (obj[which])(genome.gene(0), genome.gene(1));}voidInitializer(GAGenome& g) { GA1DArrayGenome<float>& genome = (GA1DArrayGenome<float>&)g; genome.gene(0, GARandomFloat(minx[which], maxx[which])); genome.gene(1, GARandomFloat(miny[which], maxy[which]));}intMutator(GAGenome& g, float pmut) { GA1DArrayGenome<float>& genome = (GA1DArrayGenome<float>&)g; int nmut = 0; if(GAFlipCoin(pmut)){ genome.gene(0, genome.gene(0) + 10*GARandomFloat() * (GARandomFloat() - GARandomFloat())); genome.gene(1, genome.gene(1) + 10*GARandomFloat() * (GARandomFloat() - GARandomFloat())); nmut++; } if(genome.gene(0) < minx[which]) genome.gene(0, minx[which]); if(genome.gene(0) > maxx[which]) genome.gene(0, maxx[which]); if(genome.gene(1) < minx[which]) genome.gene(1, minx[which]); if(genome.gene(1) > maxx[which]) genome.gene(1, maxx[which]); return nmut;}intCrossover(const GAGenome& g1,const GAGenome& g2,GAGenome* c1,GAGenome* c2){ GA1DArrayGenome<float>& mom = (GA1DArrayGenome<float>&)g1; GA1DArrayGenome<float>& dad = (GA1DArrayGenome<float>&)g2; int n = 0; float distance = 0.0, midpoint = 0.0; if(c1) { GA1DArrayGenome<float>& sis = (GA1DArrayGenome<float>&)*c1; distance = midpoint = 0.0; midpoint = (mom.gene(0) + dad.gene(0)) / 2; distance = fabs(mom.gene(0) - dad.gene(0)); sis.gene(0, midpoint + distance * (GARandomFloat() - GARandomFloat())); midpoint = (mom.gene(1) + dad.gene(1)) / 2; distance = fabs(mom.gene(1) - dad.gene(1)); sis.gene(1, midpoint + distance * (GARandomFloat() - GARandomFloat())); if(sis.gene(0) < minx[which]) sis.gene(0, minx[which]); if(sis.gene(0) > maxx[which]) sis.gene(0, maxx[which]); if(sis.gene(1) < minx[which]) sis.gene(1, minx[which]); if(sis.gene(1) > maxx[which]) sis.gene(1, maxx[which]); n += 1; } if(c2) { GA1DArrayGenome<float>& bro = (GA1DArrayGenome<float>&)*c2; distance = midpoint = 0.0; midpoint = (mom.gene(0) + dad.gene(0)) / 2; distance = fabs(mom.gene(0) - dad.gene(0)); bro.gene(0, midpoint + distance * (GARandomFloat() - GARandomFloat())); midpoint = (mom.gene(1) + dad.gene(1)) / 2; distance = fabs(mom.gene(1) - dad.gene(1)); bro.gene(1, midpoint + distance * (GARandomFloat() - GARandomFloat())); if(bro.gene(0) < minx[which]) bro.gene(0, minx[which]); if(bro.gene(0) > maxx[which]) bro.gene(0, maxx[which]); if(bro.gene(1) < minx[which]) bro.gene(1, minx[which]); if(bro.gene(1) > maxx[which]) bro.gene(1, maxx[which]); n += 1; } return n;}floatComparator(const GAGenome& g1, const GAGenome& g2) { GA1DArrayGenome<float>& a = (GA1DArrayGenome<float>&)g1; GA1DArrayGenome<float>& b = (GA1DArrayGenome<float>&)g2; float valx=(a.gene(0)-b.gene(0)) * (a.gene(0)-b.gene(0)); float valy=(a.gene(1)-b.gene(1)) * (a.gene(1)-b.gene(1)); return sqrt(valx+valy);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -