#include "BinaryAntColonyAlgoritm.h" #include #include #include #include #include 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&)> objectiveFunction, ObjectiveFunctionGoal goal) { outstream << "Iteration,populationNumber,objectiveFunction,binary,convergenceFactor" << std::endl; std::function op = getOperatorFromGoal(goal); Solution bestFound; 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 Pheromons with 0.5 std::vector pheromons(n); std::fill(pheromons.begin(), pheromons.end(), 0.5); std::vector population(amountOfPopulation); for (int i = 0; i < maxIteration; i++) { //Geneartion Population for (Solution& sol : population) { std::vector 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 pheromons) { //Sums the proportion to the marginal values double sum = std::transform_reduce(pheromons.begin(), pheromons.end(), 0.0, std::plus(), [](double value) {return std::abs(2*value - 1.0);}); return sum/(double)pheromons.size(); }