//Creates a new population void Population::NewPopulation(bool elitism) { Chromosome** newPop = (Chromosome**) malloc(sizeof(Chromosome*) * popSize); int i = 0; //if elitism is actived save the fittest chromosome if(elitism) { newPop[0] = population[0]; i++; } for(i; i < popSize; i++) { //Gets two chromosomes based on ranking Chromosome* x = GetRankingChromosome(); Chromosome* y = GetRankingChromosome(); newPop[i] = new Chromosome(x,y); } delete(population); population = (Chromosome**) malloc(sizeof(Chromosome*) * popSize); for(int i = 0 ; i < popSize; i++) { population[i] = newPop[i]; } delete(newPop); for(int i = 0; i < popSize; i++) { population[i]->SetPower(Fitness::GetPower(population[i])); population[i]->SetFitness(Fitness::GetFitness(population[i])); } sortPopulation(); }
//Creates a population of a given size Population::Population(int size) { population = (Chromosome**) malloc(sizeof(Chromosome*) * size); popSize = size; for(int i = 0; i < popSize; i++) { population[i] = new Chromosome(); population[i]->SetPower(Fitness::GetPower(population[i])); population[i]->SetFitness(Fitness::GetFitness(population[i])); } sortPopulation(); }
void doReproduce(){ struct Chromosome XoverPop[4]; // Small population of 4 individuals XoverPop[0] = Population[selectParent()]; // Select parent 1 XoverPop[1] = Population[selectParent()]; // Select parent 2 /*** Crossover ***/ int GeneNr; for(GeneNr = 0; GeneNr < GENETIC_PURSUERS;GeneNr++){ // Take one gene from each parent XoverPop[2].gene[GeneNr ] = XoverPop[0].gene[GeneNr]; XoverPop[3].gene[GeneNr ] = XoverPop[1].gene[GeneNr]; XoverPop[2].gene[GeneNr+1] = XoverPop[1].gene[GeneNr+1]; XoverPop[3].gene[GeneNr+1] = XoverPop[0].gene[GeneNr+1]; GeneNr++; } /*** Mutation ***/ doMutation(&XoverPop[2]); // Mutate the generated individual doMutation(&XoverPop[3]); // Mutate the generated individual /*** sort to add best individes ***/ int i = 0; for(i=2;i<4;i++) calculateFitness(&XoverPop[i]); // Calculate fitness for children sortPopulation(XoverPop, 4); // Sort after fitness addToNewPopulation(XoverPop[0]); // Add best individual to new population addToNewPopulation(XoverPop[1]); // Add second best individual to new population }
// //main controller of the evolution, this function never returns // static int run() { const double *fit; double finished=0; //double values[4]= {0.0,1.0,0.0,0.0}; //int epoch, reset_position; // as long as individual is being evaluated, print current fitness and return int n = wb_receiver_get_queue_length(receiver); if (n) { fit = (double *)wb_receiver_get_data(receiver); //gets msg[4]={fitness, finished,epoch,reset} fitness[evaluated_inds]=fit[0]; finished=fit[1]; //epoch= (int) fit[2]; //reset_position= (int) fit[3]; //if(reset_position) resetRobotPosition(); //if(1 == epoch || 3 == epoch){ //wb_supervisor_field_set_sf_rotation(pattern_rotation, values); //printf("Flag: %d, world is set.\n", epoch); //}else{ //values[3]=pi; //wb_supervisor_field_set_sf_rotation(pattern_rotation, values); //printf("\n Flag: %d, world is rotated.\n", epoch); //} // print generational info on screen char message[100]; sprintf(message, "Gen: %d Ind: %d Fit: %.2f", generation, evaluated_inds, fit[0]); wb_supervisor_set_label(0, message, 0, 0, 0.1, 0xff0000,0); wb_receiver_next_packet(receiver); } // if still evaluating the same individual, return. if (!finished) return TIME_STEP; //if not finished, !finished ==1. // when evaluation is done, an extra flag is returned in the message if(EVOLVING) { // if whole population has been evaluated if ((evaluated_inds+1) == POP_SIZE ) { // sort population by fitness sortPopulation(); // find and log current and absolute best individual bestfit=sortedfitness[0][0]; bestind=(int)sortedfitness[0][1]; if (bestfit > abs_bestfit) { abs_bestfit=bestfit; abs_bestind=bestind; logBest(); } //printf("best fit: %f\n", bestfit); //write data to files logPopulation(); //rank population, select best individuals and create new generation createNewPopulation(); generation++; if(200==generation) return 0; //printf("\nGENERATION %d\n", generation); evaluated_inds = 0; avgfit = 0.0; bestfit = -1.0; bestind = -1.0; resetRobotPosition(); wb_emitter_send(emitter, (void *)pop_bin[evaluated_inds], GENOME_LENGTH*sizeof(_Bool)); } else { // assign received fitness to individual //printf("fitness: %f\n", fitness[evaluated_inds]); evaluated_inds++; // send next genome to experiment resetRobotPosition(); wb_emitter_send(emitter, (void *)pop_bin[evaluated_inds], GENOME_LENGTH*sizeof(_Bool)); } } return TIME_STEP; }
/*** Algorithm ***/ void genAlg(int *solution) { // Main call function for Genetic Algorithm int currentGeneration=0, currentPopulation=0; int isSolved = 0; int k,i,j; int isChanged = 1; for(;GENETIC_POPULATION_SIZE<GENETIC_POPULATION_MAX_SIZE;GENETIC_POPULATION_SIZE+=GENETIC_INCREMENT_POPULATION){ for(i = GENETIC_POPULATION_SIZE; i < GENETIC_POPULATION_SIZE+GENETIC_INCREMENT_POPULATION; i++){ // Reset all genes. for(j = 0; j < GENETIC_PURSUERS; j++) for(k=0;k<GENETIC_STEPS;k++) Population[i].gene[j].allele[k] = 4; Population[i].inS4=999; // Reset fitness value (S4), just set to high value Population[i].chrSteps=999; // Reset fitness value (steps), set to high value Population[i].fitnessScore = 1; // Low value = bad solution, must be positive for(j = 0; j < GENETIC_PURSUERS; j++) for(k = 0; k < 2; k++) Population[i].gene[j].start[k] = Population[0].gene[j].start[k]; int GeneNr=0; for(GeneNr = 0; GeneNr < GENETIC_PURSUERS; GeneNr++){ // For each Gene getRandom(&(Population[i].gene[GeneNr]),0); // Generate a random step sequence } } if(isChanged == 1){ i = 0; isChanged = 0; } else{ i = GENETIC_POPULATION_SIZE; } for(; i < GENETIC_POPULATION_SIZE+GENETIC_INCREMENT_POPULATION; i++){ // Calculate fitness for population calculateFitness(&Population[i]); if(Population[i].inS4 == 0){ isSolved = 1; if(Population[i].chrSteps < GENETIC_STEPS){ isChanged = 1; GENETIC_STEPS = Population[i].chrSteps; } } } if(isSolved==1 && GENETIC_POPULATION_SIZE>GENETIC_MIN_POP_SIZE) break; } printf("genAlg\n"); printf("**** Genetic Algorithm info ****\n"); printf("Population size:\t%d\n", GENETIC_POPULATION_SIZE); printf("Pursuers:\t\t%d\n", GENETIC_PURSUERS); printf("Maximum steps:\t\t%d\n", GENETIC_STEPS); printf("Maximum generations:\t%d\n", GENETIC_GENERATIONS); printf("Convergence %%:\t\t%d\n", abs(GENETIC_CONVERGENCE_PERCENT*100)); printf("Mutation %%:\t\t%d\n", abs(GENETIC_MUTATION_PROBABILITY*100)); sortPopulation(Population, GENETIC_POPULATION_SIZE); // Sort the population after fitness for(currentGeneration = 0; currentGeneration < GENETIC_GENERATIONS; currentGeneration++){ /*** New generation ***/ /* calculateFitness(&Population[0]); printStates(); printf("Generation %d\n", currentGeneration); */ addToNewPopulation(Population[0]); // Elite selection addToNewPopulation(Population[1]); // Elite selection while(NewPopLocation < GENETIC_POPULATION_SIZE) doReproduce(); // Reproduction sortPopulation(New_Population, GENETIC_POPULATION_SIZE); // Sort the new population after fitness /*** Swap populations ***/ int i; for(i = 0; i < GENETIC_POPULATION_SIZE;i++) Population[i] = New_Population[i]; // Overwrite old population with new memcpy(Population, New_Population, sizeof New_Population); /* if(currentGeneration%1==0){ printf("Best Fitness: %f, States: %d, steps: %d\n", Population[0].fitnessScore, Population[0].inS4, Population[0].chrSteps); printf("Compare Fitness (%d): %f, States: %d, steps: %d\n", abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT), Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].fitnessScore, Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].inS4, Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].chrSteps); printf("Worst Fitness (%d): %f, States: %d, steps: %d\n", GENETIC_POPULATION_SIZE, Population[GENETIC_POPULATION_SIZE-1].fitnessScore, Population[GENETIC_POPULATION_SIZE-1].inS4, Population[GENETIC_POPULATION_SIZE-1].chrSteps); } */ if(Population[0].inS4 == 0 && Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].inS4 == 0) // If a complete solution has been found, check if convergence level is reached if((Population[0].chrSteps==Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].chrSteps)) // If 90% of the population has the same number of steps, no need to continue to do more generations. if(Population[0].fitnessScore==Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].fitnessScore) // Redundant check, check fitness score break; NewPopLocation=0; } printf("%d generations used.\n", currentGeneration); printf("Best Fitness: %f, States: %d, steps: %d\n", Population[0].fitnessScore, Population[0].inS4, Population[0].chrSteps); printf("Compare Fitness: %f, States: %d, steps: %d\n", Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].fitnessScore, Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].inS4, Population[abs(GENETIC_POPULATION_SIZE*GENETIC_CONVERGENCE_PERCENT)].chrSteps); printf("Worst Fitness: %f, States: %d, steps: %d\n", Population[GENETIC_POPULATION_SIZE-1].fitnessScore, Population[GENETIC_POPULATION_SIZE-1].inS4, Population[GENETIC_POPULATION_SIZE-1].chrSteps); solution[0]=GENETIC_PURSUERS; // Write number of pursuers to solution solution[1]=GENETIC_STEPS; // Write maximum number of steps to solution if(Population[0].chrSteps<=MAX_SIZE_SOLUTION){ doDecode(&Population[0], solution); // Decode solution to positions solution[1]=calculateStates(solution); // Calculate states, and update steps to minimum } else solution[1]=Population[0].chrSteps; // If the solution was to long, or not found, no need to return path /*** Free allocated memory ***/ free(Population); free(New_Population); /*** Free memory for NodeMatrix ***/ for(i = 0; i < ROWS;i++) free(NodeMatrix[i]); free(NodeMatrix); return; }
int main(int argc, char **argv){ tspsMap_t map; tspsConfig_t config; tspsPopulation_t population; unsigned long int numGenerations = 0; int mpiNumProcs = 0; double start, end; //starting MPI directives MPI_Init(NULL,NULL); MPI_Comm_size(MPI_COMM_WORLD,&mpiNumProcs); MPI_Comm_rank(MPI_COMM_WORLD,&mpiId); logg("* Starting tspgen...\n"); // parse the command line args if(readConfig(&config, argc, argv) != TSPS_RC_SUCCESS){ return TSPS_RC_FAILURE; } // parse the map logg("* Parsing map...\n"); if(parseMap(&map) != TSPS_RC_SUCCESS){ logg("Error! Unable to read map 'maps/brazil58.tsp'!\n"); return TSPS_RC_FAILURE; } // initialize random seed: srand ( time(NULL)*mpiId ); logg("* Generating population...\n"); if(generatePopulation(&population, &config) != TSPS_RC_SUCCESS){ logg("Error! Failed to create a new random population!"); return TSPS_RC_FAILURE; } // start a timer (mpi_barrier + mpi_wtime) MPI_Barrier(MPI_COMM_WORLD); start = MPI_Wtime(); logg("* Initializing reproduction loop...\n"); while(1){ numGenerations++; calculateFitnessPopulation(&population, &map); if(numGenerations % 500 == 0){ logg("- Generation %d...\n", numGenerations); printIndividual(&population.individuals[0], "Current Top Individual"); } sortPopulation(&population); if(config.numGenerations > 0 && numGenerations == config.numGenerations){ logg("* Max number of generations [%d] reached!\n", config.numGenerations); break; } crossoverPopulation(&population, &config); mutatePopulation(&population, &config); // migrate population at every n generation if(numGenerations % config.migrationRate == 0){ migrateIndividuals(&population, mpiId, mpiNumProcs, &config); } } // join all the populations joinPopulations(&population, mpiId, mpiNumProcs); sortPopulation(&population); // get the best inidividual and print it printIndividual(&population.individuals[0], "Top Individual"); printIndividual(&population.individuals[config.populationSize-1], "Worst (of the top ones) Individual"); // stop the timer MPI_Barrier(MPI_COMM_WORLD); /* IMPORTANT */ end = MPI_Wtime(); if(mpiId == 0) { /* use time on master node */ printf("* Runtime = %f\n", end-start); } logg("* tspgen finished!\n"); free(population.individuals); free(map.nodes); MPI_Finalize(); return TSPS_RC_SUCCESS; }