BinaryAntColonyAlgoritm.cpp 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "BinaryAntColonyAlgoritm.h"
  2. #include <algorithm>
  3. #include <limits>
  4. #include <functional>
  5. #include <numeric>
  6. #include <iostream>
  7. BinaryAntColonyOptimization::BinaryAntColonyOptimization(std::ostream& outstream, int iteration, int population, double vaporization, double resetThreshold):
  8. maxIteration(std::max(iteration, 1)), amountOfPopulation(std::max(1, population)), vaporization(std::clamp(vaporization, 0.0, 1.0)),
  9. resetThreshold(std::clamp(resetThreshold, 0.0, 1.0)), BinaryHeuristic(outstream)
  10. {
  11. }
  12. Solution BinaryAntColonyOptimization::execute(int rounds, int n, std::function<double(const std::vector<bool>&)> objectiveFunction, ObjectiveFunctionGoal goal)
  13. {
  14. outstream << "Iteration,populationNumber,objectiveFunction,binary,convergenceFactor" << std::endl;
  15. std::function<bool(double, double)> op = getOperatorFromGoal(goal);
  16. Solution bestFound;
  17. bestFound.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits<double>::max() : std::numeric_limits<double>::min();
  18. for (int r = 0; r < rounds; r++) {
  19. Solution bestFoundInRun;
  20. //init with Worst Value
  21. bestFoundInRun.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits<double>::max() : std::numeric_limits<double>::min();
  22. //Init Pheromons with 0.5
  23. std::vector<double> pheromons(n);
  24. std::fill(pheromons.begin(), pheromons.end(), 0.5);
  25. std::vector<Solution> population(amountOfPopulation);
  26. for (int i = 0; i < maxIteration; i++) {
  27. //Geneartion Population
  28. for (Solution& sol : population) {
  29. std::vector<bool> bitstring(n);
  30. std::transform(pheromons.begin(), pheromons.end(), bitstring.begin(),
  31. [this](double pheromon)->bool {return rand.doubleRandom() < pheromon; });
  32. sol.bitstring = bitstring;
  33. sol.objectiveFunctionValue = objectiveFunction(sol.bitstring);
  34. //UpdateBest
  35. if (op(sol.objectiveFunctionValue, bestFoundInRun.objectiveFunctionValue)) {
  36. bestFoundInRun = sol;
  37. }
  38. }
  39. //Reset
  40. double convergenceFactor = calculateConvergenceFactor(pheromons);
  41. if (convergenceFactor >= resetThreshold) {
  42. std::fill(pheromons.begin(), pheromons.end(), 0.5);
  43. }
  44. for (int k = 0; k < population.size() - 1; k++) {
  45. outstream << r << "," << i << "," << k << "," << population[k].objectiveFunctionValue << ","
  46. << population[k].bitstringToStdString() << "," << convergenceFactor << std::endl;
  47. }
  48. //UpdatePheromons
  49. std::cout << "BestFound:" << bestFoundInRun.bitstringToStdString() << " with value:" << bestFoundInRun.objectiveFunctionValue << " cF:" << convergenceFactor << std::endl;
  50. for (int bit = 0; bit < n; bit++) {
  51. bool bestDecision = bestFoundInRun.bitstring[bit];
  52. pheromons[bit] = (1.0 - vaporization) * pheromons[bit] + (bestDecision ? vaporization : 0.0);
  53. }
  54. }
  55. //update best run
  56. if (op(bestFoundInRun.objectiveFunctionValue, bestFound.objectiveFunctionValue)) {
  57. bestFound = bestFoundInRun;
  58. }
  59. }
  60. return bestFound;
  61. }
  62. double BinaryAntColonyOptimization::calculateConvergenceFactor(std::vector<double> pheromons)
  63. {
  64. //Sums the proportion to the marginal values
  65. double sum = std::transform_reduce(pheromons.begin(), pheromons.end(), 0.0, std::plus<double>(), [](double value) {return std::abs(2*value - 1.0);});
  66. return sum/(double)pheromons.size();
  67. }