GeneticAlgorithm.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "GeneticAlgorithm.h"
  2. #include <iostream>
  3. GeneticAlgorithm::GeneticAlgorithm(std::ostream& outstream, int iteration, int population, double mutateProbability, double swapProbability, double tournamentSize):
  4. iteration(iteration), populationSize(population), mutateProbability(mutateProbability), swapProbability(swapProbability), tournamentSize(tournamentSize), BinaryHeuristic(outstream)
  5. {
  6. }
  7. Solution GeneticAlgorithm::execute(int rounds, int n, std::function<double(const std::vector<bool>&)> objectiveFunction, ObjectiveFunctionGoal goal)
  8. {
  9. outstream << "round,iteration,populationNumber,objectiveFunction,binary" << std::endl;
  10. std::function<bool(double, double)> op = getOperatorFromGoal(goal);
  11. Solution bestFound;
  12. //init with Worst Value
  13. bestFound.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits<double>::max() : std::numeric_limits<double>::min();
  14. for (int r = 0; r < rounds; r++) {
  15. Solution bestFoundInRun;
  16. //init with Worst Value
  17. bestFoundInRun.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits<double>::max() : std::numeric_limits<double>::min();
  18. //Init populattion
  19. std::vector<Solution> population(populationSize);
  20. std::vector<Solution> childList(populationSize);
  21. for (Solution& sol : population) {
  22. std::vector<bool> bitstring(n);
  23. std::generate(bitstring.begin(), bitstring.end(), [this]() {return rand.doubleRandom() < 0.5; });
  24. sol.bitstring = bitstring;
  25. }
  26. for (int i = 0; i < iteration; i++) {
  27. //Evaluate
  28. for (Solution& sol : population) {
  29. sol.objectiveFunctionValue = objectiveFunction(sol.bitstring);
  30. //UpdateBest
  31. if (op(sol.objectiveFunctionValue, bestFoundInRun.objectiveFunctionValue)) {
  32. bestFoundInRun = sol;
  33. }
  34. }
  35. for (int k = 0; k < population.size() - 1; k++) {
  36. outstream << r << "," << i << "," << k << "," << population[k].objectiveFunctionValue << ","
  37. << population[k].bitstringToStdString() << std::endl;
  38. }
  39. //GenerateChildren
  40. for (int k = 0; k < populationSize / 2; k++) {
  41. childList[2 * k] = selectAParent(population, op);
  42. childList[2 * k + 1] = selectAParent(population, op);
  43. crossover(childList[2 * k], childList[2 * k + 1]);
  44. mutate(childList[2 * k]);
  45. mutate(childList[2 * k + 1]);
  46. }
  47. //Exchange generations
  48. std::swap(population, childList);
  49. std::cout << "BestFound:" << bestFoundInRun.bitstringToStdString() << " with value:" << bestFoundInRun.objectiveFunctionValue << std::endl;
  50. }
  51. //update best run
  52. if (op(bestFoundInRun.objectiveFunctionValue, bestFound.objectiveFunctionValue)) {
  53. bestFound = bestFoundInRun;
  54. }
  55. }
  56. return bestFound;
  57. }
  58. Solution& GeneticAlgorithm::selectAParent(std::vector<Solution>& population, std::function<bool(double, double)> op)
  59. {
  60. Solution* tournamentBest = &population[rand.randomIntegerInRange(0, populationSize)];
  61. double participants;
  62. for (participants = tournamentSize; participants >= 2; participants -= 1.0) {
  63. Solution& next = population[rand.randomIntegerInRange(0, populationSize)];
  64. if (op(next.objectiveFunctionValue,tournamentBest->objectiveFunctionValue)) tournamentBest = &next;
  65. }
  66. //if decimal participant stays in tournament its a chance to play another
  67. if (participants > 1) {
  68. if (rand.doubleRandom() < participants - 1.0) {
  69. Solution& next = population[rand.randomIntegerInRange(0, populationSize)];
  70. if (op(next.objectiveFunctionValue, tournamentBest->objectiveFunctionValue)) tournamentBest = &next;
  71. }
  72. }
  73. return *tournamentBest;
  74. }
  75. void GeneticAlgorithm::crossover(Solution& parentA, Solution& parentB)
  76. {
  77. std::vector<bool>::iterator iterA= parentA.bitstring.begin();
  78. std::vector<bool>::iterator iterB= parentB.bitstring.begin();
  79. for (int i = 0; i < parentA.bitstring.size(); i++) {
  80. if (rand.doubleRandom() <= swapProbability) {
  81. //Swap
  82. std::iter_swap(iterA, iterB);
  83. }
  84. iterA++;
  85. iterB++;
  86. }
  87. }
  88. void GeneticAlgorithm::mutate(Solution& individual)
  89. {
  90. std::transform(individual.bitstring.begin(), individual.bitstring.end(), individual.bitstring.begin(), [this](bool bit) {
  91. return (rand.doubleRandom() < mutateProbability) ? !bit : bit;
  92. });
  93. }