//filename: GAClass.cpp #include #include #include #include #include //for black box 's fitness evaluation //double eval(int *); // for De Jong function 1 's fitness evaluation double eval1(int *); void decode1(int *, double &, double &, double &); // for De Jong function 2 's fitness evaluation double eval2(int *); void decode2(int *, double &, double &); // for De Jong function 3 's fitness evaluation double eval3(int *); void decode3( int *,double *); // for De Jong function 4 's fitness evaluation double eval4(int *); void decode4(int *, double *); //-------------------------------------------------------------- // Class: for single chromosome: // declaration and definition //-------------------------------------------------------------- class Chromosome { public: int *chrom; double fitness; Chromosome(int chromSize); Chromosome() { }; void initialize(int); private: int size; }; /* Chromosome::Chromosome(int chromSize) { size = chromSize; chrom = new int [chromSize]; } */ void Chromosome::initialize(int chromSize) { size = chromSize; chrom = new int [chromSize]; for (int i = 0; i < size; i++) chrom[i] = rand() % 2; return; } //-------------------------------------------------------------- // Class: for whole population // declaration and definition //-------------------------------------------------------------- class Population { public: Population(int, int, int); void initialize(double, double); void evolution(); //private: Chromosome *oldChroms; Chromosome *newChroms; Chromosome *temp; //for temporary use Chromosome maxChrom; double maxFitness; double sumFitness; double avgFitness; double currentMaxFit; double currentMinFit; int currentMaxChromIndex; int chromLength; int popSize; int totalNumGenerations; int currentGenNum; double crossProbability; double mutateProbability; void swapPop(); int flip(double); void mutate(Chromosome *); void evaluate(); void statistics(); int roulette(); void crossover(int, int, int, int); void generateNewPop(); void reportResult(); }; Population::Population(int chromL, int popS, int totalNumGens) { int i; oldChroms = new Chromosome [popS]; newChroms = new Chromosome [popS]; totalNumGenerations = totalNumGens; popSize = popS; chromLength = chromL; } void Population::initialize(double crossP, double mutateP) { int i; //srand(time(0)); //srand48(time(0)); crossProbability = crossP; mutateProbability = mutateP; for (i = 0; i < popSize; i++) { oldChroms[i].initialize(chromLength); newChroms[i].initialize(chromLength); } maxChrom.initialize(chromLength); maxFitness = 0.0; currentMaxFit = 0.0; currentMinFit = 99999.9; currentMaxChromIndex = -1; currentGenNum = 0; sumFitness = 0.0; avgFitness = 0.0; return; } void Population::swapPop() { temp = oldChroms; oldChroms = newChroms; newChroms = temp; return; } void Population::evaluate() { for (int i = 0; i < popSize; i++) { //oldChroms[i].fitness = eval1(oldChroms[i].chrom); //oldChroms[i].fitness = eval2(oldChroms[i].chrom); oldChroms[i].fitness = eval3(oldChroms[i].chrom); //oldChroms[i].fitness = eval4(oldChroms[i].chrom); } return; } //calculate sumFitness avgFitness, and // the maxFitness and its corresponding // chromosome void Population::statistics() { int i; currentMaxFit = 0.0; currentMinFit = 99999.9; currentMaxChromIndex = -1; sumFitness = 0.0; avgFitness = 0.0; for (i = 0; i < popSize; i++) { sumFitness += oldChroms[i].fitness; if (oldChroms[i].fitness > currentMaxFit) { currentMaxFit = oldChroms[i].fitness; currentMaxChromIndex = i; } if (oldChroms[i].fitness < currentMinFit) { currentMinFit = oldChroms[i].fitness; } } avgFitness = sumFitness / popSize; } void Population::reportResult() { maxChrom.fitness = maxFitness; cout<chrom[k] = (chr->chrom[k] + 1) % 2; } } int Population::roulette() { int k; double hitSum, randNum, accumulateSum; hitSum = drand48() * sumFitness; accumulateSum = 0.0; k = 0; while ((k < popSize) && (accumulateSum <= hitSum)) { accumulateSum += oldChroms[k].fitness; k++; } k--; return k; } void Population::crossover(int p1, int p2, int c1, int c2) { int i, k; if (flip(crossProbability)) { k = rand() % chromLength; for (i = 0; i < k; i++) { newChroms[c1].chrom[i] = oldChroms[p1].chrom[i]; newChroms[c2].chrom[i] = oldChroms[p2].chrom[i]; } for (i = k; i < chromLength; i++) { newChroms[c1].chrom[i] = oldChroms[p2].chrom[i]; newChroms[c2].chrom[i] = oldChroms[p1].chrom[i]; } } else for (i = 0; i < chromLength; i++) { newChroms[c1].chrom[i] = oldChroms[p1].chrom[i]; newChroms[c2].chrom[i] = oldChroms[p2].chrom[i]; } mutate(&newChroms[c1]); mutate(&newChroms[c2]); } void Population::generateNewPop() { int i, p1, p2; for (i = 0; i< popSize; i += 2) { p1 = roulette(); p2 = roulette(); crossover(p1, p2, i, i+1); } } void Population::evolution() { for (int i = 0; i < totalNumGenerations; i++) { currentGenNum = i; evaluate(); statistics(); reportResult(); generateNewPop(); swapPop(); } } // for De Jong function 1 's fitness evaluation // with the use CMAX = 100.0 for adjusment // of the fitness double eval1(int *vec) { double x,y,z; x = y = z = 0.0; decode1(vec,x,y,z); return (100.0 - ((x*x)+(y*y)+(z*z))); } void decode1( int *vec,double &x,double &y,double &z ) { int i; double k; x = y = z = 0.0; for (i = 1; i < 10; i++) { k = pow(2, i - 1); x += vec[i] * k; y += vec[10 + i] * k; z += vec[20 + i] * k; } k = pow(2, 9); x -= vec[0] * k; x /= 100.0; y -= vec[10] * k; y /= 100.0; z -= vec[20] * k; z /= 100.0; return; } // for De Jong function 2 's fitness evaluation // with the use CMAX = 4000.0 for adjusment // of the fitness double eval2(int *vec) { double x,y, result; x = y = 0.0; decode2(vec,x,y); result = 100*((x*x) - y)*((x*x) - y); result += ((1-x)*(1-x)); return( 4000.0 - result); } void decode2( int *vec,double &x,double &y ) { int i; double k; x = y = 0.0; for (i = 1; i < 12; i++) { k = pow(2, i - 1); x += vec[i] * k; y += vec[12 + i] * k; } k = pow (2, 11); x -= vec[0] * k; x /= 1000.0; y -= vec[12] * k; y /= 1000.0; return; } // for De Jong function 3 's fitness evaluation // with the use CMAX = 30 for adjusment // of the fitness double eval3(int *vec) { int i; double s; double x[5]; for (i = 0; i < 5; i++) x[i] = 0.0; s = 0; decode3(vec,x); for (i = 0; i < 5; i++) s += x[i]; return (30 - s); } void decode3( int *vec,double *x ) { int i, j; double k; for (i = 0; i < 5; i++) x[i] = 0.0; for (i = 1; i < 10; i++) { k = pow(2, i - 1); for (j = 0; j < 5; j++) x[j] += vec[j * 10 + i] * k; } k = pow(2, 9); for (j = 0; j < 5; j++) { x[j] -= vec[j * 10] * k; x[j] /= 100.0; } return; } // for De Jong function 4 's fitness evaluation // with the use CMAX = 1300.0 for adjusment // of the fitness double eval4(int *vec) { int i; double result, randD, x[30]; for(i=0;i<30;i++) x[i]=0; result = 0.0; decode4(vec,x); for(i = 0; i < 30; i++){ randD= drand48(); if(rand() % 2) randD *= -1; result += (i + 1) * pow(x[i],4) + randD; } //result += randD; return (1300.0 - result ); } void decode4( int *vec,double *x) { int i, j; double k; for (j = 0; j < 30; j++) x[j] = 0; for (i = 1; i < 8; i++) { k = pow(2, i - 1); for (j = 0; j < 30; j++) x[j] += vec[j * 8 + i] * k; } k = pow(2, 7); for (j = 0; j < 30; j++) { x[j] -= vec[j * 8] * k; x[j] /= 100.0; } return; }