void Population::Evolve() { //std::vector<Chromosome> buffer; //buffer.resize(chromosome_population_.size()); std::uniform_real_distribution<float> crossover_decider(0,1); //buffer.resize(chromosome_population_.size()); int top_candidates_pivot = (int) (chromosome_population_.size() * elitism_); std::vector<Chromosome>::const_iterator first = chromosome_population_.begin(); std::vector<Chromosome>::const_iterator last = chromosome_population_.begin() + top_candidates_pivot; std::vector<Chromosome> buffer(&chromosome_population_[0], &chromosome_population_[top_candidates_pivot]); buffer.resize(chromosome_population_.size()); //buffer(first,last); //std::copy(chromosome_population_.begin(),chromosome_population_.begin() + // top_candidates_pivot, std::back_inserter(buffer)); while(top_candidates_pivot < buffer.size()-1) { if(crossover_decider(rng_.mt_rng_) <= crossover_) { std::vector<Chromosome> parents = SelectParents(); std::vector<Chromosome> children = parents[0].Mate(parents[1]); if(crossover_decider(rng_.mt_rng_) <= mutation_) { buffer[top_candidates_pivot+1] = children[0].Mutate(); } else { buffer[top_candidates_pivot+1] = children[0]; } if(top_candidates_pivot < buffer.size()) { if(crossover_decider(rng_.mt_rng_) <= mutation_) { buffer[top_candidates_pivot] = children[1].Mutate(); } else { buffer[top_candidates_pivot] = children[1]; } } } else { if(crossover_decider(rng_.mt_rng_) <= mutation_) { buffer[top_candidates_pivot] = chromosome_population_[1].Mutate(); } else { buffer[top_candidates_pivot] = chromosome_population_[1]; } } ++top_candidates_pivot; } std::sort(buffer.begin(), buffer.end(), ChromosomeLessThan()); chromosome_population_= buffer; }
void GA::Execute(){ std::cout << "Solving TSP\n"; SDL_Window *window = NULL; //SDL_Surface *surface; SDL_Init(SDL_INIT_VIDEO); const int wWidth = 640; const int wHeight = 480; window = SDL_CreateWindow("TSP Visualizer",SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, wWidth,wHeight,SDL_WINDOW_OPENGL); //surface = SDL_GetWindowSurface(window); SDL_UpdateWindowSurface(window); SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); std::vector<SDL_Rect> cityDots; for(const auto& c : baseCityVector){ SDL_Rect dot; dot.x = c.getX() * wWidth / maxXPosition - 2; dot.y = c.getY() * wHeight / maxYPosition - 2; dot.w = 4; dot.h = 4; cityDots.push_back(dot); } for(int g = 1; g < targetGenerationNumber; g++){ currentGeneration = g; std::cout << "Current generation: " << g << "\n"; SortCandidates(); //std::cout << "Sorted population\n"; parentsPopulation.clear(); SelectParents(populationBreadersPercentage); int childrenPopulationSize = populationSize * populationBreadersPercentage / 100; //std::cout << "Childrem population size: " << childrenPopulationSize << "\n"; while(newPopulation.size() < childrenPopulationSize){ //std::cout << "New pop size: " << newPopulation.size() << "\n"; auto parent1 = parentsPopulation.at( std::rand() % parentsPopulation.size() ); auto parent2 = parentsPopulation.at( std::rand() % parentsPopulation.size() ); //std::future<Candidate> fChild1 = std::async(GA::PMXCrossover,parent1,parent2); Candidate child1 = PMXCrossover(parent1,parent2); Candidate child2 = PMXCrossover(parent2,parent1); //if(std::find(newPopulation.begin(),newPopulation.end(),child) == newPopulation.end()) newPopulation.push_back ( child1 ); newPopulation.push_back ( child2 ); } //std::cout << "Created new population\n"; for(int m = 1; m <= newPopulation.size() * mutationPercentage / 100; m++){ //auto mutant = newPopulation[std::rand() % newPopulation.size()]; auto mutant = newPopulation[ (std::rand() * m) % newPopulation.size()]; Mutate(mutant, mutationPower); mutant.ReEvaluate(distances); } //std::cout << "Mutated population\n"; population.insert(population.end(), newPopulation.begin(), newPopulation.end()); newPopulation.clear(); NormalizeCandidates(); SortCandidates(); population = std::vector<Candidate>(population.begin(),population.begin()+populationSize); std::cout << "Best: " << population.at(0) << "\n"; SDL_SetRenderDrawColor(renderer, 255,255,255,255); SDL_RenderClear(renderer); std::vector<SDL_Point> cityPositions; /* int maxX; int maxY; for(const auto& city : getBest().getCandidate()){ maxX = 0; maxY = 0; if(city.getX() > maxX) maxX = city.getX(); if(city.getY() > maxY) maxY = city.getY(); } */ for(const auto& city : population[0].getCandidate()){ int posY = city.getY() * wHeight / maxYPosition; int posX = city.getX() * wWidth / maxXPosition; SDL_Point position; position.y = city.getY() * wHeight / maxYPosition; position.x = city.getX() * wWidth / maxXPosition; cityPositions.push_back(position); } SDL_SetRenderDrawColor(renderer, 255,0,0,255); SDL_RenderDrawLines(renderer, &cityPositions[0], cityPositions.size()); SDL_SetRenderDrawColor(renderer, 0,255,0,255); SDL_RenderFillRects(renderer, &cityDots[0], cityDots.size()); SDL_RenderPresent(renderer); /* if(renderer == NULL){ SDL_RenderDrawLine(renderer, g*10, g, 250, 250); } */ } SDL_DestroyWindow(window); SDL_Quit(); }