#include "GeneticAlgorithm.h" #include GeneticAlgorithm::GeneticAlgorithm(std::ostream& outstream, int iteration, int population, double mutateProbability, double swapProbability, double tournamentSize): iteration(iteration), populationSize(population), mutateProbability(mutateProbability), swapProbability(swapProbability), tournamentSize(tournamentSize), BinaryHeuristic(outstream) { } Solution GeneticAlgorithm::execute(int rounds, int n, std::function&)> objectiveFunction, ObjectiveFunctionGoal goal) { outstream << "round,iteration,populationNumber,objectiveFunction,binary" << std::endl; std::function op = getOperatorFromGoal(goal); Solution bestFound; //init with Worst Value bestFound.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits::max() : std::numeric_limits::min(); for (int r = 0; r < rounds; r++) { Solution bestFoundInRun; //init with Worst Value bestFoundInRun.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits::max() : std::numeric_limits::min(); //Init populattion std::vector population(populationSize); std::vector childList(populationSize); for (Solution& sol : population) { std::vector bitstring(n); std::generate(bitstring.begin(), bitstring.end(), [this]() {return rand.doubleRandom() < 0.5; }); sol.bitstring = bitstring; } for (int i = 0; i < iteration; i++) { //Evaluate for (Solution& sol : population) { sol.objectiveFunctionValue = objectiveFunction(sol.bitstring); //UpdateBest if (op(sol.objectiveFunctionValue, bestFoundInRun.objectiveFunctionValue)) { bestFoundInRun = sol; } } for (int k = 0; k < population.size() - 1; k++) { outstream << r << "," << i << "," << k << "," << population[k].objectiveFunctionValue << "," << population[k].bitstringToStdString() << std::endl; } //GenerateChildren for (int k = 0; k < populationSize / 2; k++) { childList[2 * k] = selectAParent(population, op); childList[2 * k + 1] = selectAParent(population, op); crossover(childList[2 * k], childList[2 * k + 1]); mutate(childList[2 * k]); mutate(childList[2 * k + 1]); } //Exchange generations std::swap(population, childList); std::cout << "BestFound:" << bestFoundInRun.bitstringToStdString() << " with value:" << bestFoundInRun.objectiveFunctionValue << std::endl; } //update best run if (op(bestFoundInRun.objectiveFunctionValue, bestFound.objectiveFunctionValue)) { bestFound = bestFoundInRun; } } return bestFound; } Solution& GeneticAlgorithm::selectAParent(std::vector& population, std::function op) { Solution* tournamentBest = &population[rand.randomIntegerInRange(0, populationSize)]; double participants; for (participants = tournamentSize; participants >= 2; participants -= 1.0) { Solution& next = population[rand.randomIntegerInRange(0, populationSize)]; if (op(next.objectiveFunctionValue,tournamentBest->objectiveFunctionValue)) tournamentBest = &next; } //if decimal participant stays in tournament its a chance to play another if (participants > 1) { if (rand.doubleRandom() < participants - 1.0) { Solution& next = population[rand.randomIntegerInRange(0, populationSize)]; if (op(next.objectiveFunctionValue, tournamentBest->objectiveFunctionValue)) tournamentBest = &next; } } return *tournamentBest; } void GeneticAlgorithm::crossover(Solution& parentA, Solution& parentB) { std::vector::iterator iterA= parentA.bitstring.begin(); std::vector::iterator iterB= parentB.bitstring.begin(); for (int i = 0; i < parentA.bitstring.size(); i++) { if (rand.doubleRandom() <= swapProbability) { //Swap std::iter_swap(iterA, iterB); } iterA++; iterB++; } } void GeneticAlgorithm::mutate(Solution& individual) { std::transform(individual.bitstring.begin(), individual.bitstring.end(), individual.bitstring.begin(), [this](bool bit) { return (rand.doubleRandom() < mutateProbability) ? !bit : bit; }); }