Browse Source

Aco Algorithm for Topologie

Troppmann, Tom 3 years ago
parent
commit
17139a9411
1 changed files with 181 additions and 0 deletions
  1. 181 0
      src/algorithm/topologie/AcoAlgorithm.java

+ 181 - 0
src/algorithm/topologie/AcoAlgorithm.java

@@ -0,0 +1,181 @@
+package algorithm.topologie;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import algorithm.objectiveFunction.ObjectiveFunctionByCarlos;
+import algorithm.objectiveFunction.TopologieObjectiveFunction;
+import api.TopologieAlgorithmFramework;
+import api.AlgorithmFrameworkFlex.Individual;
+import ui.model.DecoratedState;
+
+public class AcoAlgorithm extends TopologieAlgorithmFramework {
+
+	private int popsize = 20;
+	private int maxGenerations = 100;
+	private boolean moreInformation = false;
+	/**
+	 * The vaporization factor;
+	 */
+	private double p = 0.05;
+	private double convergenceFactorReset = 0.90;
+	
+	public AcoAlgorithm(){
+		addIntParameter("popsize", popsize, intValue -> popsize = intValue, () -> popsize, 1);
+		addIntParameter("maxGenerations", maxGenerations, intValue -> maxGenerations = intValue, () -> maxGenerations, 1);
+		addDoubleParameter("Vaporization", p, doubleValue -> p = doubleValue, () -> p, 0.0, 1.0);
+		addDoubleParameter("FactorReset", convergenceFactorReset, doubleValue -> convergenceFactorReset = doubleValue, () -> convergenceFactorReset, 0.0, 1.0);
+		addBooleanParameter("moreInformation", moreInformation, booleanValue -> moreInformation = booleanValue);
+
+	}
+	@Override
+	protected double evaluateState(DecoratedState actualstate) {
+		return TopologieObjectiveFunction.getFitnessValueForState(actualstate);
+	}
+
+	@Override
+	protected Individual executeAlgo() {
+		resetWildcards();
+		Individual best = new Individual();
+		best.position = extractPositionAndAccess();
+		int problemSize =  best.position.size();
+		best.fitness = evaluatePosition(best.position);
+		List<Double> runList = new ArrayList<Double>();
+		runList.add(best.fitness);
+		console.println("Integer_Array_length: " + best.position.size());
+		List<List<Double>> pheromones = initPheromones(problemSize);
+		List<Individual> population = new ArrayList<Individual>();
+		if(moreInformation)console.println("Size To Test:" + population.size());
+		for(int generation = 0; generation< maxGenerations; generation++) {
+			population.clear();
+			population = constructSolutionsBiasedBy(pheromones);
+			if(moreInformation)console.println("Generation" + generation + " start with Fitness: " + best.fitness);
+			for(Individual i : population) {
+				i.fitness = evaluatePosition(i.position);
+				if(moreInformation)console.println("Fitness" + i.fitness);
+				if(i.fitness < best.fitness) best = i;	
+			}
+			runList.add(best.fitness);
+			if(moreInformation)console.println("________________");
+			vaporizeIntensifiePheromons(pheromones, best.position, problemSize);
+			double cf = calculateConvergenceFactor(pheromones, problemSize);
+			if(moreInformation)console.println("ConvergenceFactor = " + cf);
+			if(moreInformation)console.println("pheromones:" + pheromones);
+			if(cf > this.convergenceFactorReset) {
+				pheromones = initPheromones(problemSize);
+			}
+			if(cancel)return null;
+		}
+		console.println("   End with:" + best.fitness);
+		this.runList = runList;
+		return best;
+	}
+
+	@Override
+	protected int getProgressBarMaxCount() {
+		return rounds * maxGenerations * popsize + 1;
+	}
+
+	@Override
+	protected String algoInformationToPrint() {
+		return "GA for topologie generation";
+	}
+
+	@Override
+	protected String plottFileName() {
+		return "ga-topologie.txt";
+	}
+	/**
+	 * tj1 is the pheromon level in the j position
+	 * cf is the convergence factor cf e [0;1]
+	 * 
+	 * 
+	 * 
+	 * @param pheromones
+	 * @return cf
+	 */
+	private double calculateConvergenceFactor(List<List<Double>> pheromones,int problemSize) {
+		double sumofmax = pheromones.stream().map(listPheromons -> listPheromons.stream().max((a,b) -> Double.compare(a,b)).get()).reduce(0.0, Double::sum);
+		double cf = sumofmax / (double)problemSize;
+		return cf;
+	}
+	/**
+	 * pheromone <- (1-p) * pheromone;
+	 * if(best is true at this position) pheromone <- pheromone + p;
+	 * @param pheromones
+	 * @param position
+	 */
+	private void vaporizeIntensifiePheromons(List<List<Double>> pheromones, List<Integer> position, int problemSize) {
+		ListIterator<List<Double>> iterPheromone = pheromones.listIterator();
+		ListIterator<Integer> iterBest = position.listIterator();
+		for(int i = 0; i < problemSize; i++) {
+			List<Double> tauList = iterPheromone.next();
+			int bestDecision = iterBest.next();
+			ListIterator<Double> tauListiter = tauList.listIterator();
+			for(int k = 0; tauListiter.hasNext(); k++) {
+				double value = tauListiter.next();
+				tauListiter.set((1.0 - p) * value + (k == bestDecision?p:0.0));
+			}
+		}
+	}
+	/**
+	 * 
+	 * @param pheromones
+	 * @return
+	 */
+	private List<Individual> constructSolutionsBiasedBy(List<List<Double>> pheromones) {
+		List<Individual> population =  new ArrayList<Individual>();
+		for(int i = 0; i < popsize; i++) {
+			population.add(constructASolutionBiasedBy(pheromones));
+		}
+		return population;
+	}
+	
+	
+	/**
+	 * Walks the path with a ant and decide by pheromones if should take true or false;
+	 * A pheromone have a level of 0 < pheromone < 1.
+	 * A Pheromone is  equal to the probability.
+	 * @param pheromones
+	 * @return
+	 */
+	private Individual constructASolutionBiasedBy(List<List<Double>> pheromones) {
+		Individual result = new Individual();
+		result.position = new ArrayList<Integer>();
+		for(List<Double> pheromoneList : pheromones) {
+			ListIterator<Double> tauListiter = pheromoneList.listIterator();
+			double radnomValue = Random.nextDouble();
+			for(int i = 0;tauListiter.hasNext(); i++) {
+				double actualtau = tauListiter.next();
+				if(radnomValue > actualtau) {
+					radnomValue -= actualtau;
+				}else {
+					result.position.add(i);
+					break;
+				}
+			}
+		}
+		return result;
+	}
+	/**
+	 * Initialize Pheromons with 1.0 / maxIndex;
+	 */
+	private List<List<Double>> initPheromones(int problemSize) {
+		List<List<Double>> result = new ArrayList<List<Double>>();
+		for(int i = 0; i < problemSize;i++) {
+			//generate list equal tau values with max Int
+			int maxIndex = this.getMaximumIndexObjects(i);
+			double tauValue = 1.0 / (double) (maxIndex + 1);
+			List<Double> tauList = new ArrayList<Double>();
+			for(int tau= 0; tau < maxIndex + 1; tau++) {
+				tauList.add(tauValue);				
+			}
+			result.add(tauList);
+		}
+		return result;
+	}
+}
+