TourPopulation * TourGA::evolvePopulation(TourPopulation * pop) { TourPopulation * newPop = new TourPopulation(pop->populationSize(), false); int elitismOffset = 0; if (TourGA::elitism) { newPop->saveTour(0, pop->getFittest()); elitismOffset = 1; } for (int eIndex = elitismOffset; eIndex < newPop->populationSize(); eIndex++) { Tour * parent1 = tournamentSelection(pop); Tour * parent2 = tournamentSelection(pop); Tour * child = crossover(parent1, parent2); newPop->saveTour(eIndex, child); } for (int eIndex = elitismOffset; eIndex < newPop->populationSize(); eIndex++) { mutate(newPop->getTour(eIndex)); } return newPop; }
void CGeneticSystem::stepGeneration(){ //stepGeneration2(); //return; std::vector<CChromo> newPopulation(m_populationSize*2); for(int i = 0; i < m_populationSize*2; i++) { CChromo p(m_noCitys , m_distMatrix); newPopulation[i] = p; } int newPopulationSize = 0; SortPopulation(m_ChromoPopulation,false); computeFitness(); for(int i = 0; i < m_populationSize; i++) { for(int j = 0; j < m_noCitys; j++) { int test = m_ChromoPopulation[i].getGene(j); newPopulation[i].setGene(j,test ); } newPopulationSize++; } while(newPopulationSize < 2*m_populationSize) { int idx1 =0; //tournamentSelection(); int idx2 =0; //tournamentSelection(); while(idx1 == idx2) { idx2= tournamentSelection(); idx1= tournamentSelection(); } CChromo &pfather=m_ChromoPopulation[idx2]; CChromo &pMother=m_ChromoPopulation[idx1]; CChromo p_offspring1(m_noCitys,m_distMatrix) , p_offspring2(m_noCitys,m_distMatrix); pMother.crossover(&pfather, &p_offspring1, &p_offspring2); newPopulation[newPopulationSize] = p_offspring1; newPopulationSize++; if(newPopulationSize >= newPopulation.size()) break; newPopulation[newPopulationSize] = p_offspring2; newPopulationSize++; } mutatePopulation(newPopulation); SortPopulation(newPopulation , true); //ass for(int i = 0; i < m_populationSize-2; i++) //keep last best { m_ChromoPopulation[i] = newPopulation[i]; } SortPopulation(m_ChromoPopulation , true); updateBestSoFarPath(); }
void CGeneticSystem::stepGeneration2() { std::vector<CChromo> newPopulation(m_populationSize*2); for(int i = 0; i < m_populationSize*2; i++) { CChromo p(m_noCitys , m_distMatrix); newPopulation[i] = p; } int newPopulationSize = 0; SortPopulation(m_ChromoPopulation , false); computeFitness(); for(int i = 0; i < m_populationSize; i++) { for(int j = 0; j < m_noCitys; j++) { int test = m_ChromoPopulation[i].getGene(j); newPopulation[i].setGene(j,test ); } newPopulationSize++; } while (newPopulationSize < 2*m_populationSize) { int idx1 = tournamentSelection(); int idx2 = tournamentSelection(); CChromo offspring = m_ChromoPopulation[idx1].CrossOver2(&m_ChromoPopulation[idx2]); newPopulation[newPopulationSize] = offspring; newPopulationSize++; } mutatePopulation(newPopulation); SortPopulation(newPopulation , true); for(int i = 0; i < m_populationSize; i++) { m_ChromoPopulation[i] = newPopulation[i]; } SortPopulation(m_ChromoPopulation,true); updateBestSoFarPath(); }
int main(int argc, char * argv[]){ Population * pop, * selected; Individual * best_solution; int generation_num; initParameters(argc, argv); pop = genSeededPopulation(POP_SIZE); #if (defined DIVERSITY) printGeneComposition(pop); #endif determineFitness(pop); sortByFitness(pop); generation_num = 0; while(generation_num < MAX_NUM_GENERATIONS){ #if (defined VERBOSE || defined DIVERSITY) fprintf(stdout, "\n----------------- GENERATION %d -----------------\n", generation_num + 1); printPopulation(pop); #endif // FIX - use function pointers instead of flags + if statement if(selection_type == 1) selected = tournamentSelection(pop); else selected = randomSelection(pop); // FIX - use function pointers instead of flags + if statement evolvePopulation(selected, crossover_type, mutation_type); determineFitness(selected); // FIX - use function pointers instead of flags + if statement if(replacement_type == 1) pop = replaceAll(pop, selected); else pop = retainBest(pop, selected); generation_num++; } fprintf(stdout, "\nFINAL RESULT:\n"); printPopulation(pop); fprintf(stdout, "\nBEST SOLUTION:\n"); best_solution = findBest(pop); printIndividual(best_solution); freePopulation(pop); freeParameters(); return EXIT_SUCCESS; }
void selection::adultAndParentSelection(vector<individual*> &juveniles, vector<individual*> &adults, vector<individual*> &parents, int populationSize, int elitism){ parents.clear(); int count = populationSize - elitism; sort(juveniles.begin(), juveniles.end(), fitnessSortFunc); for(int i = 0; i < elitism; i++){ parents.push_back(juveniles[i]); } if(selectionProtocol == FULLGENREP){ //Use the entire new generation fullGenReplacement(juveniles, adults); } else if(selectionProtocol == OVERPROD){ //Limit number of adults spots for the new generation overProduction(juveniles, adults); } else { //protocol = GENMIXING){ //Survival of the fittest (both generations) generationMixing(juveniles, adults, count, elitism); } juveniles.clear(); if(selectionMechanism == FITNESS){ //Fitness proportionate fitnessProportionate(adults, parents, count); } else if(selectionMechanism == SIGMA){ //Sigma Scaling sigmaScaling(adults, parents, count); } else if(selectionMechanism == RANK){ //Rank Selection rankSelection(adults, parents, count); } else { //selectionMechanism == TOURNAMENT //Tournament selection tournamentSelection(adults, parents, count, elitism); } }
/* This function performs one epoch of the genetic algorithm and returns * a vector of pointers to the new phenotypes */ void epoch(sPopulation * pop) { int spec, gen; // reset appropriate values and kill off the existing phenotypes and // any poorly performing species resetAndKill(pop); // sort genomes sortGenomes(pop); // separate the population into species of similar topology, adjust // fitnesses and calculate spawn levels speciateAndCalculateSpawnLevels(pop); if (Verbose) dumpSpecies(stdout, pop); if (GlobalLog) dumpSpecies(GlobalLogFile, pop); // this will hold the new population of genomes sGenome ** newGenomes = calloc( pop->sParams->iNumIndividuals, sizeof(*newGenomes) ); // request the offspring from each species. The number of children to // spawn is a double which we need to convert to an int. int numSpawnedSoFar = 0; sGenome * baby; // now to iterate through each species selecting offspring to be mated and // mutated for (spec = 0; spec < pop->iNumSpecies; spec++) { // because of the number to spawn from each species is a double // rounded up or down to an integer it is possible to get an overflow // of genomes spawned. This statement just makes sure that doesn't happen if (numSpawnedSoFar < pop->sParams->iNumIndividuals) { //this is the amount of offspring this species is required to // spawn. Round simply rounds the double up or down. int numToSpawn = round(pop->vSpecies[spec]->dSpawnsRqd); bool bChosenBestYet = E_FALSE; while (numToSpawn--) { // first grab the best performing genome from this species and transfer // to the new population without mutation. This provides per species // elitism // => Stanley recommends to do this only if the species has more than // five networks, in Neat1.1 he used the futur number of individual // instead of the current one... if (!bChosenBestYet) { // && numToSpawn > 5 baby = copyGenome(pop->vSpecies[spec]->sLeader); bChosenBestYet = E_TRUE; } else { // if the number of individuals in this species is only one // then we can only perform mutation if (pop->vSpecies[spec]->iNumMembers == 1) { // spawn a child baby = copyGenome(randomAmongBest( pop->vSpecies[spec], pop->sParams->dSurvivalRate )); } //if greater than one we can use the crossover operator else { // spawn1 sGenome * g1 = randomAmongBest( pop->vSpecies[spec], pop->sParams->dSurvivalRate ); if (randFloat() < pop->sParams->dCrossoverRate) { // spawn2, make sure it's not the same as g1 sGenome * g2 = randomAmongBest( pop->vSpecies[spec], pop->sParams->dSurvivalRate ); // number of attempts at finding a different genome int numAttempts = pop->sParams->iNumTrysToFindMate; while (g1->iId == g2->iId && numAttempts--) g2 = randomAmongBest( pop->vSpecies[spec], pop->sParams->dSurvivalRate); if (g1->iId != g2->iId) baby = crossover(g1, g2); else baby = copyGenome(g1); // crossover fail } else { baby = copyGenome(g1); // no crossover } } // adjust new genome id baby->iId = pop->iNextGenomeId++; // now we have a spawned child lets mutate it! First there is the // chance a neuron may be added if (randFloat() < pop->sParams->dChanceAddNode) addNeuron(baby, pop); // now there's the chance a link may be added else if (randFloat() < pop->sParams->dChanceAddLink) addLink(baby, pop); else { // mutate the weights mutateWeigth(baby, pop->sParams); // mutate the activation response mutateActivationResponse(baby, pop->sParams); // enable or disable a random gene if (randFloat() < 0.1) // mutate_toggle_enable_prob = 0.1 mutateToggleEnable(baby); // find first disabled gene and enable it if (randFloat() < 0.05) // mutate_gene_reenable_prob = 0.05 mutateReenableFirst(baby); } } // end choice of a baby //sort the babies genes by their innovation numbers qsort(baby->vLinks, baby->iNumLinks, sizeof(sLinkGene *), (int (*) (const void *, const void *)) cmpLinksByInnovIds); //add to new pop newGenomes[numSpawnedSoFar++] = baby; if (numSpawnedSoFar == pop->sParams->iNumIndividuals) goto newGenerationReady; } // end while not enougth babies } // end if to much babies } // next species // if there is an underflow due to the rounding error and the amount // of offspring falls short of the population size additional children // need to be created and added to the new population. This is achieved // simply, by using tournament selection over the entire population. if (numSpawnedSoFar < pop->sParams->iNumIndividuals) { //calculate amount of additional children required int rqd = pop->sParams->iNumIndividuals - numSpawnedSoFar; //grab them while (rqd--) { sGenome * chosenOne = tournamentSelection(pop, pop->iNumGenomes / 5); newGenomes[numSpawnedSoFar++] = copyGenome(chosenOne); } } newGenerationReady: // free the old vector of genomes for (gen = 0; gen < pop->iNumGenomes; gen++) freeGenome(pop->vGenomes[gen]); // free the genome itself free(pop->vGenomes); // free the vector containing the genomes //replace the current population with the new one pop->vGenomes = newGenomes; //create the new phenotypes for (gen = 0; gen < pop->iNumGenomes; gen++) { if (UltraVerbose) dumpGenome(stdout, pop->vGenomes[gen]); //calculate max network depth //int depth = calculateNetDepth(pop->vGenomes[gen]); createPhenotype(pop->vGenomes[gen], pop->iNumDepth + pop->vGenomes[gen]->iNumRecur); if (UltraVerbose) dumpPhenotype(pop->vGenomes[gen]->pPhenotype, pop->vGenomes[gen]->iId); } //increase generation counter pop->iGeneration++; }