1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- #include "BinaryAntColonyAlgoritm.h"
- #include <algorithm>
- #include <limits>
- #include <functional>
- #include <numeric>
- #include <iostream>
- BinaryAntColonyOptimization::BinaryAntColonyOptimization(std::ostream& outstream, int iteration, int population, double vaporization, double resetThreshold):
- maxIteration(std::max(iteration, 1)), amountOfPopulation(std::max(1, population)), vaporization(std::clamp(vaporization, 0.0, 1.0)),
- resetThreshold(std::clamp(resetThreshold, 0.0, 1.0)), BinaryHeuristic(outstream)
- {
- }
- Solution BinaryAntColonyOptimization::execute(int rounds, int n, std::function<double(const std::vector<bool>&)> objectiveFunction, ObjectiveFunctionGoal goal)
- {
- outstream << "Iteration,populationNumber,objectiveFunction,binary,convergenceFactor" << std::endl;
- std::function<bool(double, double)> op = getOperatorFromGoal(goal);
- Solution bestFound;
- bestFound.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits<double>::max() : std::numeric_limits<double>::min();
-
- for (int r = 0; r < rounds; r++) {
- Solution bestFoundInRun;
- //init with Worst Value
- bestFoundInRun.objectiveFunctionValue = (goal == ObjectiveFunctionGoal::min) ? std::numeric_limits<double>::max() : std::numeric_limits<double>::min();
- //Init Pheromons with 0.5
- std::vector<double> pheromons(n);
- std::fill(pheromons.begin(), pheromons.end(), 0.5);
- std::vector<Solution> population(amountOfPopulation);
- for (int i = 0; i < maxIteration; i++) {
- //Geneartion Population
- for (Solution& sol : population) {
- std::vector<bool> bitstring(n);
- std::transform(pheromons.begin(), pheromons.end(), bitstring.begin(),
- [this](double pheromon)->bool {return rand.doubleRandom() < pheromon; });
- sol.bitstring = bitstring;
- sol.objectiveFunctionValue = objectiveFunction(sol.bitstring);
- //UpdateBest
- if (op(sol.objectiveFunctionValue, bestFoundInRun.objectiveFunctionValue)) {
- bestFoundInRun = sol;
- }
- }
- //Reset
- double convergenceFactor = calculateConvergenceFactor(pheromons);
- if (convergenceFactor >= resetThreshold) {
- std::fill(pheromons.begin(), pheromons.end(), 0.5);
- }
- for (int k = 0; k < population.size() - 1; k++) {
- outstream << r << "," << i << "," << k << "," << population[k].objectiveFunctionValue << ","
- << population[k].bitstringToStdString() << "," << convergenceFactor << std::endl;
- }
- //UpdatePheromons
- std::cout << "BestFound:" << bestFoundInRun.bitstringToStdString() << " with value:" << bestFoundInRun.objectiveFunctionValue << " cF:" << convergenceFactor << std::endl;
- for (int bit = 0; bit < n; bit++) {
- bool bestDecision = bestFoundInRun.bitstring[bit];
- pheromons[bit] = (1.0 - vaporization) * pheromons[bit] + (bestDecision ? vaporization : 0.0);
- }
- }
- //update best run
- if (op(bestFoundInRun.objectiveFunctionValue, bestFound.objectiveFunctionValue)) {
- bestFound = bestFoundInRun;
- }
- }
-
- return bestFound;
- }
- double BinaryAntColonyOptimization::calculateConvergenceFactor(std::vector<double> pheromons)
- {
- //Sums the proportion to the marginal values
- double sum = std::transform_reduce(pheromons.begin(), pheromons.end(), 0.0, std::plus<double>(), [](double value) {return std::abs(2*value - 1.0);});
- return sum/(double)pheromons.size();
- }
|