AcoAlgorithm.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package holeg.algorithm.binary;
  2. import holeg.api.AlgorithmFrameworkFlex;
  3. import holeg.utility.math.decimal.Format;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import java.util.ListIterator;
  7. import javax.swing.JFrame;
  8. public class AcoAlgorithm extends AlgorithmFrameworkFlex {
  9. //Parameter for Algo with default Values:
  10. /**
  11. * Should be even.
  12. */
  13. private int popsize = 20;
  14. private int maxGenerations = 200;
  15. /**
  16. * The vaporization factor;
  17. */
  18. private double p = 0.3;
  19. private double convergenceFactorReset = 0.99;
  20. private boolean moreInformation = false;
  21. public AcoAlgorithm() {
  22. super();
  23. addIntParameter("Population size", popsize, intValue -> popsize = intValue, () -> popsize, 1);
  24. addIntParameter("Generations", maxGenerations, intValue -> maxGenerations = intValue,
  25. () -> maxGenerations, 1);
  26. addDoubleParameter("Vaporization rate", p, doubleValue -> p = doubleValue, () -> p, 0.0, 1.0);
  27. addDoubleParameter("Convergence factor threshold", convergenceFactorReset,
  28. doubleValue -> convergenceFactorReset = doubleValue, () -> convergenceFactorReset, 0.0,
  29. 1.0);
  30. addBooleanParameter("Detailed information", moreInformation,
  31. booleanValue -> moreInformation = booleanValue);
  32. }
  33. public static void main(String[] args) {
  34. JFrame newFrame = new JFrame("exampleWindow");
  35. AcoAlgorithm instance = new AcoAlgorithm();
  36. newFrame.setContentPane(instance.getPanel());
  37. newFrame.pack();
  38. newFrame.setVisible(true);
  39. newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  40. }
  41. @Override
  42. protected int getProgressBarMaxCount() {
  43. return rounds * popsize * maxGenerations;
  44. }
  45. /**
  46. * Algorithm 20 !! Fitness is better when smaller.: PseudoCode: Best <- actual; pheromones =
  47. * initPheromons(); for(maxGeneration times){ population = createSolutionsBiasedBy(pheromones);
  48. * for(each Individual i from population){ fitness <- evaluatePosition(i); if(fitness <
  49. * best.fitnessValue) Best <- i; } vaporizeIntensifiePheromons(pheromones); }
  50. *
  51. * @return
  52. */
  53. @Override
  54. protected Individual executeAlgo() {
  55. Individual best = new Individual();
  56. best.position = extractPositionAndAccess();
  57. if (moreInformation) {
  58. console.println("Bit-Array_length: " + best.position.size());
  59. }
  60. best.fitness = evaluatePosition(best.position);
  61. List<Double> runList = new ArrayList<Double>();
  62. runList.add(best.fitness);
  63. console.print("Start with: " + Format.doubleFixedPlaces(2, best.fitness));
  64. if (moreInformation) {
  65. console.println("");
  66. }
  67. if (best.position.isEmpty()) {
  68. return best;
  69. }
  70. int problemSize = best.position.size();
  71. List<Double> pheromones = initPheromones(problemSize);
  72. List<Individual> population = new ArrayList<Individual>();
  73. if (moreInformation) {
  74. console.println("Size To Test:" + population.size());
  75. }
  76. for (int generation = 0; generation < maxGenerations; generation++) {
  77. population.clear();
  78. population = constructSolutionsBiasedBy(pheromones);
  79. if (moreInformation) {
  80. console.println("Generation" + generation + " start with Fitness: " + best.fitness);
  81. }
  82. for (Individual i : population) {
  83. i.fitness = evaluatePosition(i.position);
  84. if (moreInformation) {
  85. console.println("Fitness" + Format.doubleFixedPlaces(2, i.fitness));
  86. }
  87. if (i.fitness < best.fitness) {
  88. best = i;
  89. }
  90. }
  91. runList.add(best.fitness);
  92. if (moreInformation) {
  93. console.println("________________");
  94. }
  95. vaporizeIntensifiePheromons(pheromones, best.position, problemSize);
  96. double cf = calculateConvergenceFactor(pheromones, problemSize);
  97. if (moreInformation) {
  98. console.println("ConvergenceFactor = " + cf);
  99. }
  100. if (cf > this.convergenceFactorReset) {
  101. pheromones = initPheromones(problemSize);
  102. }
  103. if (cancel) {
  104. return null;
  105. }
  106. }
  107. console.println(" End With:" + Format.doubleFixedPlaces(2, best.fitness));
  108. this.runList = runList;
  109. return best;
  110. }
  111. /**
  112. * tj1 is the pheromon level in the j position cf is the convergence factor cf e [0;1] difference
  113. * = | tj1 - tj0 | = | tj1 - (1 - tj1) |
  114. *
  115. * @param pheromones
  116. * @return cf
  117. */
  118. private double calculateConvergenceFactor(List<Double> pheromones, int problemSize) {
  119. double sumOfDifference = pheromones.stream().map(tj1 -> Math.abs(tj1 - (1.0 - tj1)))
  120. .reduce(0.0, Double::sum);
  121. double cf = sumOfDifference / (double) problemSize;
  122. return cf;
  123. }
  124. /**
  125. * pheromone <- (1-p) * pheromone; if(best is true at this position) pheromone <- pheromone + p;
  126. *
  127. * @param pheromones
  128. * @param position
  129. */
  130. private void vaporizeIntensifiePheromons(List<Double> pheromones, List<Boolean> position,
  131. int problemSize) {
  132. ListIterator<Double> iterPheromone = pheromones.listIterator();
  133. ListIterator<Boolean> iterBest = position.listIterator();
  134. for (int i = 0; i < problemSize; i++) {
  135. double pheromone = iterPheromone.next();
  136. boolean bestDecision = iterBest.next();
  137. iterPheromone.set((1.0 - p) * pheromone + (bestDecision ? p : 0.0));
  138. }
  139. }
  140. /**
  141. * @param pheromones
  142. * @return
  143. */
  144. private List<Individual> constructSolutionsBiasedBy(List<Double> pheromones) {
  145. List<Individual> population = new ArrayList<Individual>();
  146. for (int i = 0; i < popsize; i++) {
  147. population.add(constructASolutionBiasedBy(pheromones));
  148. }
  149. return population;
  150. }
  151. /**
  152. * Walks the path with a ant and decide by pheromones if should take true or false; A pheromone
  153. * have a level of 0 < pheromone < 1. A Pheromone is equal to the probability.
  154. *
  155. * @param pheromones
  156. * @return
  157. */
  158. private Individual constructASolutionBiasedBy(List<Double> pheromones) {
  159. Individual result = new Individual();
  160. result.position = new ArrayList<Boolean>();
  161. for (double pheromone : pheromones) {
  162. result.position.add((Random.nextDouble() < pheromone));
  163. }
  164. return result;
  165. }
  166. /**
  167. * Initialize Pheromons with 0.5
  168. */
  169. private List<Double> initPheromones(int problemSize) {
  170. List<Double> result = new ArrayList<Double>();
  171. for (int i = 0; i < problemSize; i++) {
  172. result.add(0.5);
  173. }
  174. return result;
  175. }
  176. @Override
  177. protected String algoInformationToPrint() {
  178. // private int popsize = 20;
  179. // private int maxGenerations = 200;
  180. // private double p = 0.3;
  181. // private double convergenceFactorReset = 0.99;
  182. return "AcoAlgo"
  183. + " Rounds: " + rounds
  184. + " Iterations: " + maxGenerations
  185. + " Individuals: " + popsize
  186. + " vaporization: " + Format.doubleAllPlaces(p)
  187. + " convergenceFactorReset: " + Format.doubleAllPlaces(convergenceFactorReset);
  188. }
  189. @Override
  190. protected String plottFileName() {
  191. return "plottAcoAlgo.txt";
  192. }
  193. }