AcoAlgorithm.java 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package holeg.algorithm.topologie;
  2. import holeg.algorithm.objective_function.TopologieObjectiveFunction;
  3. import holeg.api.TopologieAlgorithmFramework;
  4. import holeg.model.Model;
  5. import holeg.utility.math.Random;
  6. import java.util.ArrayList;
  7. import java.util.LinkedList;
  8. import java.util.List;
  9. import java.util.ListIterator;
  10. public class AcoAlgorithm extends TopologieAlgorithmFramework {
  11. private int popsize = 20;
  12. private int maxGenerations = 100;
  13. private boolean moreInformation = false;
  14. /**
  15. * The vaporization factor;
  16. */
  17. private double p = 0.05;
  18. private double convergenceFactorReset = 0.90;
  19. public AcoAlgorithm() {
  20. addIntParameter("popsize", popsize, intValue -> popsize = intValue, () -> popsize, 1);
  21. addIntParameter("maxGenerations", maxGenerations, intValue -> maxGenerations = intValue,
  22. () -> maxGenerations, 1);
  23. addSeperator();
  24. addDoubleParameter("Vaporization", p, doubleValue -> p = doubleValue, () -> p, true, 0.0, 1.0);
  25. addDoubleParameter("FactorReset", convergenceFactorReset,
  26. doubleValue -> convergenceFactorReset = doubleValue, () -> convergenceFactorReset, true,
  27. 0.0, 1.0);
  28. addSeperator();
  29. addBooleanParameter("moreInformation", moreInformation,
  30. booleanValue -> moreInformation = booleanValue, new LinkedList<String>(),
  31. new LinkedList<String>());
  32. }
  33. @Override
  34. protected double evaluateState(Model model, int amountOfAddedSwitch, double addedCableMeters,
  35. boolean moreInformation) {
  36. return TopologieObjectiveFunction.getFitnessValueForState(model, amountOfAddedSwitch,
  37. addedCableMeters, moreInformation);
  38. }
  39. @Override
  40. protected Individual executeAlgo() {
  41. resetWildcards();
  42. Individual best = new Individual();
  43. best.position = extractPositionAndAccess();
  44. int problemSize = best.position.size();
  45. best.fitness = evaluatePosition(best.position);
  46. List<Double> runList = new ArrayList<Double>();
  47. runList.add(best.fitness);
  48. console.println("Integer_Array_length: " + best.position.size());
  49. List<List<Double>> pheromones = initPheromones(problemSize);
  50. List<Individual> population = new ArrayList<Individual>();
  51. if (moreInformation) {
  52. console.println("Size To Test:" + population.size());
  53. }
  54. for (int generation = 0; generation < maxGenerations; generation++) {
  55. population.clear();
  56. population = constructSolutionsBiasedBy(pheromones);
  57. if (moreInformation) {
  58. console.println("Generation" + generation + " start with Fitness: " + best.fitness);
  59. }
  60. for (Individual i : population) {
  61. i.fitness = evaluatePosition(i.position);
  62. if (moreInformation) {
  63. console.println("Fitness" + i.fitness);
  64. }
  65. if (i.fitness < best.fitness) {
  66. best = i;
  67. }
  68. }
  69. runList.add(best.fitness);
  70. if (moreInformation) {
  71. console.println("________________");
  72. }
  73. vaporizeIntensifiePheromons(pheromones, best.position, problemSize);
  74. double cf = calculateConvergenceFactor(pheromones, problemSize);
  75. if (moreInformation) {
  76. console.println("ConvergenceFactor = " + cf);
  77. }
  78. if (moreInformation) {
  79. console.println("pheromones:" + pheromones);
  80. }
  81. if (cf > this.convergenceFactorReset) {
  82. pheromones = initPheromones(problemSize);
  83. }
  84. if (cancel) {
  85. return null;
  86. }
  87. }
  88. console.println(" End with:" + best.fitness);
  89. this.runList = runList;
  90. return best;
  91. }
  92. @Override
  93. protected int getProgressBarMaxCount() {
  94. return rounds * maxGenerations * popsize + 1;
  95. }
  96. @Override
  97. protected String algoInformationToPrint() {
  98. return "Aco for Topologie " + " Rounds:" + rounds
  99. + " maxGenerations:" + maxGenerations
  100. + " popsize:" + popsize
  101. + " vaporization:" + p
  102. + " convergenceFactorReset:" + convergenceFactorReset;
  103. }
  104. @Override
  105. protected String plottFileName() {
  106. return "aco-topologie.txt";
  107. }
  108. /**
  109. * tj1 is the pheromon level in the j position cf is the convergence factor cf e [0;1]
  110. *
  111. * @param pheromones
  112. * @return cf
  113. */
  114. private double calculateConvergenceFactor(List<List<Double>> pheromones, int problemSize) {
  115. double sumofmax = pheromones.stream()
  116. .map(listPheromons -> listPheromons.stream().max((a, b) -> Double.compare(a, b)).get())
  117. .reduce(0.0, Double::sum);
  118. double cf = sumofmax / (double) problemSize;
  119. return cf;
  120. }
  121. /**
  122. * pheromone <- (1-p) * pheromone; if(best is true at this position) pheromone <- pheromone + p;
  123. *
  124. * @param pheromones
  125. * @param position
  126. */
  127. private void vaporizeIntensifiePheromons(List<List<Double>> pheromones, List<Integer> position,
  128. int problemSize) {
  129. ListIterator<List<Double>> iterPheromone = pheromones.listIterator();
  130. ListIterator<Integer> iterBest = position.listIterator();
  131. for (int i = 0; i < problemSize; i++) {
  132. List<Double> tauList = iterPheromone.next();
  133. int bestDecision = iterBest.next();
  134. ListIterator<Double> tauListiter = tauList.listIterator();
  135. for (int k = 0; tauListiter.hasNext(); k++) {
  136. double value = tauListiter.next();
  137. tauListiter.set((1.0 - p) * value + (k == bestDecision ? p : 0.0));
  138. }
  139. }
  140. }
  141. /**
  142. * @param pheromones
  143. * @return
  144. */
  145. private List<Individual> constructSolutionsBiasedBy(List<List<Double>> pheromones) {
  146. List<Individual> population = new ArrayList<Individual>();
  147. for (int i = 0; i < popsize; i++) {
  148. population.add(constructASolutionBiasedBy(pheromones));
  149. }
  150. return population;
  151. }
  152. /**
  153. * Walks the path with a ant and decide by pheromones if should take true or false; A pheromone
  154. * have a level of 0 < pheromone < 1. A Pheromone is equal to the probability.
  155. *
  156. * @param pheromones
  157. * @return
  158. */
  159. private Individual constructASolutionBiasedBy(List<List<Double>> pheromones) {
  160. Individual result = new Individual();
  161. result.position = new ArrayList<Integer>();
  162. for (List<Double> pheromoneList : pheromones) {
  163. ListIterator<Double> tauListiter = pheromoneList.listIterator();
  164. double radnomValue = Random.nextDouble();
  165. for (int i = 0; tauListiter.hasNext(); i++) {
  166. double actualtau = tauListiter.next();
  167. if (radnomValue > actualtau) {
  168. radnomValue -= actualtau;
  169. } else {
  170. result.position.add(i);
  171. break;
  172. }
  173. }
  174. }
  175. return result;
  176. }
  177. /**
  178. * Initialize Pheromons with 1.0 / maxIndex;
  179. */
  180. private List<List<Double>> initPheromones(int problemSize) {
  181. List<List<Double>> result = new ArrayList<List<Double>>();
  182. for (int i = 0; i < problemSize; i++) {
  183. //generate list equal tau values with max Int
  184. int maxIndex = this.getMaximumIndexObjects(i);
  185. double tauValue = 1.0 / (double) (maxIndex + 1);
  186. List<Double> tauList = new ArrayList<Double>();
  187. for (int tau = 0; tau < maxIndex + 1; tau++) {
  188. tauList.add(tauValue);
  189. }
  190. result.add(tauList);
  191. }
  192. return result;
  193. }
  194. }