AcoAlgorithm.java 6.6 KB

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