PsoAlgorithm2.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. package exampleAlgorithms;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.TreeSet;
  5. import java.util.stream.Collectors;
  6. import javax.swing.JFrame;
  7. import api.AlgorithmFramework;
  8. import ui.model.DecoratedState;
  9. public class PsoAlgorithm2 extends AlgorithmFramework{
  10. //Parameter for Algo with default Values:
  11. private int swarmSize = 20;
  12. private int maxIterations = 100;
  13. private double limit = 0.01;
  14. private double dependency = 2.07;
  15. private int mutationInterval = 1;
  16. private boolean useIntervalMutation = true;
  17. private double mutateProbabilityInterval = 0.01;
  18. private double maxMutationPercent = 0.01;
  19. private double c1, c2, w;
  20. public static void main(String[] args)
  21. {
  22. JFrame newFrame = new JFrame("exampleWindow");
  23. PsoAlgorithm2 instance = new PsoAlgorithm2();
  24. newFrame.setContentPane(instance.getPanel());
  25. newFrame.pack();
  26. newFrame.setVisible(true);
  27. newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  28. }
  29. public PsoAlgorithm2() {
  30. super();
  31. addIntParameter("swarmSize", swarmSize, intValue -> swarmSize = intValue, 1);
  32. addIntParameter("maxIterations", maxIterations, intValue -> maxIterations = intValue, 1);
  33. addIntParameter("mutationInterval", mutationInterval, intValue -> mutationInterval = intValue, 0);
  34. addDoubleParameter("dependency", dependency, doubleValue -> dependency = doubleValue, 2.001, 2.4);
  35. addDoubleParameter("limit", limit, doubleValue -> limit = doubleValue, 0.0, 1.0);
  36. addBooleanParameter("useIntervalMutation", useIntervalMutation, booleanValue -> useIntervalMutation = booleanValue);
  37. addDoubleParameter("mutateProbabilityInterval", mutateProbabilityInterval, doubleValue -> mutateProbabilityInterval = doubleValue, 0.0, 1.0);
  38. addDoubleParameter("maxMutationPercent", maxMutationPercent, doubleValue -> maxMutationPercent = doubleValue, 0.0, 1.0);
  39. }
  40. @Override
  41. protected double evaluateState(DecoratedState actualstate) {
  42. return Evaluation.getFitnessValueForState(actualstate);
  43. }
  44. @Override
  45. protected int getProgressBarMaxCount() {
  46. return swarmSize * (maxIterations + 1)* rounds + rounds;
  47. }
  48. /**
  49. * <p>Algo from Paper:</p><font size="3"><pre>
  50. *
  51. * Begin
  52. * t = 0; {t: generation index}
  53. * initialize particles x<sub>p,i,j</sub>(t);
  54. * evaluation x<sub>p,i,j</sub>(t);
  55. * while (termination condition &ne; true) do
  56. * v<sub>i,j</sub>(t) = update v<sub>i,j</sub>(t); {by Eq. (6)}
  57. * x<sub>g,i,j</sub>(t) = update x<sub>g,i,j</sub>(t); {by Eq. (7)}
  58. * x<sub>g,i,j</sub>(t) = mutation x<sub>g,i,j</sub>(t); {by Eq. (11)}
  59. * x<sub>p,i,j</sub>(t) = decode x<sub>g,i,j</sub>(t); {by Eqs. (8) and (9)}
  60. * evaluate x<sub>p,i,j</sub>(t);
  61. * t = t + 1;
  62. * end while
  63. * End</pre></font>
  64. * <p>with:</p><font size="3">
  65. *
  66. * x<sub>g,i,j</sub>: genotype ->genetic information -> in continuous space<br>
  67. * x<sub>p,i,j</sub>: phenotype -> observable characteristics-> in binary space<br>
  68. * X<sub>g,max</sub>: is the Maximum here set to 4.<br>
  69. * Eq. (6):v<sub>i,j</sub>(t + 1) = wv<sub>i,j</sub>+c<sub>1</sub>R<sub>1</sub>(P<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))+c<sub>2</sub>R<sub>2</sub>(g<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))<br>
  70. * Eq. (7):x<sub>g,i,j</sub>(t + 1) = x<sub>g,i,j</sub>(t) + v<sub>i,j</sub>(t + 1)<br>
  71. * Eq. (11):<b>if(</b>rand()&lt;r<sub>mu</sub><b>)then</b> x<sub>g,i,j</sub>(t + 1) = -x<sub>g,i,j</sub>(t + 1)<br>
  72. * Eq. (8):x<sub>p,i,j</sub>(t + 1) = <b>(</b>rand() &lt; S(x<sub>g,i,j</sub>(t + 1))<b>) ?</b> 1 <b>:</b> 0<br>
  73. * Eq. (9) Sigmoid:S(x<sub>g,i,j</sub>(t + 1)) := 1/(1 + e<sup>-x<sub>g,i,j</sub>(t + 1)</sup>)<br></font>
  74. * <p>Parameter:</p>
  75. * w inertia, calculated from phi(Variable:{@link #dependency})<br>
  76. * c1: influence, calculated from phi(Variable:{@link #dependency}) <br>
  77. * c2: influence, calculated from phi(Variable:{@link #dependency})<br>
  78. * r<sub>mu</sub>: probability that the proposed operation is conducted defined by limit(Variable:{@link #limit})<br>
  79. *
  80. *
  81. */
  82. @Override
  83. protected Individual executeAlgo() {
  84. initDependentParameter();
  85. Individual globalBest = new Individual();
  86. globalBest.position = extractPositionAndAccess();
  87. globalBest.fitness = evaluatePosition(globalBest.position);
  88. console.println("Start Value:" + globalBest.fitness);
  89. int dimensions = globalBest.position.size();
  90. List<Particle> swarm= initializeParticles(dimensions);
  91. List<Double> runList = new ArrayList<Double>();
  92. runList.add(globalBest.fitness);
  93. evaluation(globalBest, swarm);
  94. runList.add(globalBest.fitness);
  95. for (int iteration = 0; iteration < maxIterations ; iteration++) {
  96. int mutationAllowed = iteration % mutationInterval;
  97. for (int particleNumber = 0; particleNumber < swarmSize; particleNumber++) {
  98. Particle particle = swarm.get(particleNumber);
  99. if(this.useIntervalMutation) {
  100. boolean allowMutation = (Random.nextDouble() < this.mutateProbabilityInterval);
  101. TreeSet<Integer> mutationLocation = null;
  102. if(allowMutation)mutationLocation = locationsToMutate(dimensions);
  103. for(int index = 0; index < dimensions; index++) {
  104. updateVelocity(particle, index, globalBest);
  105. updateGenotype(particle, index);
  106. if(allowMutation &&mutationAllowed == 0 && iteration != 0 && mutationLocation.contains(index))mutation(particle, index);
  107. decode(particle, index);
  108. }
  109. }else {
  110. for(int index = 0; index < dimensions; index++) {
  111. updateVelocity(particle, index, globalBest);
  112. updateGenotype(particle, index);
  113. if(mutationAllowed == 0 && iteration != 0)mutation(particle, index);
  114. decode(particle, index);
  115. }
  116. }
  117. }
  118. if(cancel)return null;
  119. evaluation(globalBest, swarm);
  120. runList.add(globalBest.fitness);
  121. }
  122. console.println(" End Value:" + globalBest.fitness);
  123. db.insertNewRun(runList);
  124. return globalBest;
  125. }
  126. /**
  127. *
  128. * @param j maximum index of position in the particle
  129. * @return
  130. */
  131. private List<Particle> initializeParticles(int j) {
  132. List<Particle> swarm = new ArrayList<Particle>();
  133. //Create The Particle
  134. for (int particleNumber = 0; particleNumber < swarmSize; particleNumber++){
  135. //Create a Random position
  136. List<Boolean> aRandomPosition = new ArrayList<Boolean>();
  137. for (int index = 0; index < j; index++){
  138. aRandomPosition.add(Random.nextBoolean());
  139. }
  140. swarm.add(new Particle(aRandomPosition));
  141. }
  142. return swarm;
  143. }
  144. /**
  145. * Calculate w, c1, c2
  146. */
  147. private void initDependentParameter() {
  148. w = 1.0 / (dependency - 1 + Math.sqrt(dependency * dependency - 2 * dependency));
  149. c1 = c2 = dependency * w;
  150. }
  151. /**
  152. * Evaluate each particle and update the global Best position;
  153. * @param globalBest
  154. * @param swarm
  155. */
  156. private void evaluation(Individual globalBest, List<Particle> swarm) {
  157. for(Particle p: swarm) {
  158. double localEvaluationValue = evaluatePosition(p.xPhenotype);
  159. p.checkNewEvaluationValue(localEvaluationValue);
  160. if(localEvaluationValue < globalBest.fitness) {
  161. globalBest.fitness = localEvaluationValue;
  162. globalBest.position = p.localBest.position;
  163. }
  164. }
  165. }
  166. /**
  167. * Eq. (6):v<sub>i,j</sub>(t + 1) = wv<sub>i,j</sub>+c<sub>1</sub>R<sub>1</sub>(P<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))+c<sub>2</sub>R<sub>2</sub>(g<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))<br>
  168. * @param particle
  169. * @param index
  170. * @param globalBest
  171. */
  172. private void updateVelocity(Particle particle, int index, Individual globalBest) {
  173. double r1 = Random.nextDouble();
  174. double r2 = Random.nextDouble();
  175. double posValue = particle.xPhenotype.get(index)?1.0:0.0;
  176. particle.velocity.set(index, clamp(w*particle.velocity.get(index) + c1*r1*((particle.localBest.position.get(index)?1.0:0.0) - posValue) + c2*r2*((globalBest.position.get(index)?1.0:0.0)- posValue)) );
  177. }
  178. /**
  179. * Eq. (7):x<sub>g,i,j</sub>(t + 1) = x<sub>g,i,j</sub>(t) + v<sub>i,j</sub>(t + 1)<br>
  180. * @param particle
  181. * @param index
  182. */
  183. private void updateGenotype(Particle particle, int index) {
  184. particle.xGenotype.set(index, clamp(particle.xGenotype.get(index) + particle.velocity.get(index)));
  185. }
  186. /**
  187. * Eq. (11):<b>if(</b>rand()&lt;r<sub>mu</sub><b>)then</b> x<sub>g,i,j</sub>(t + 1) = -x<sub>g,i,j</sub>(t + 1)<br>
  188. * @param particle
  189. * @param index
  190. */
  191. private void mutation(Particle particle, int index) {
  192. if(Random.nextDouble() < limit) particle.xGenotype.set(index, -particle.xGenotype.get(index));
  193. }
  194. /**
  195. * Eq. (8):x<sub>p,i,j</sub>(t + 1) = <b>(</b>rand() &lt; S(x<sub>g,i,j</sub>(t + 1))<b>) ?</b> 1 <b>:</b> 0<br>
  196. * @param particle
  197. * @param index
  198. */
  199. private void decode(Particle particle, int index) {
  200. particle.xPhenotype.set(index, Random.nextDouble() < Sigmoid(particle.xGenotype.get(index)));
  201. }
  202. /**
  203. * Eq. (9) Sigmoid:S(x<sub>g,i,j</sub>(t + 1)) := 1/(1 + e<sup>-x<sub>g,i,j</sub>(t + 1)</sup>)<br></font>
  204. * @param value
  205. * @return
  206. */
  207. private double Sigmoid(double value) {
  208. return 1.0 / (1.0 + Math.exp(-value));
  209. }
  210. /**
  211. * To clamp X<sub>g,j,i</sub> and v<sub>i,j</sub> in Range [-X<sub>g,max</sub>|+X<sub>g,max</sub>] with {X<sub>g,max</sub>= 4}
  212. * @param value
  213. * @return
  214. */
  215. private double clamp(double value) {
  216. return Math.max(-4.0, Math.min(4.0, value));
  217. }
  218. private TreeSet<Integer> locationsToMutate(int dimensions) {
  219. TreeSet<Integer> mutationLocation = new TreeSet<Integer>(); //sortedSet
  220. int maximumAmountOfMutatedBits = Math.max(1, (int)Math.round(((double) dimensions) * this.maxMutationPercent));
  221. int randomUniformAmountOfMutatedValues = Random.nextIntegerInRange(1,maximumAmountOfMutatedBits + 1);
  222. for(int i = 0; i< randomUniformAmountOfMutatedValues; i++) {
  223. boolean success = mutationLocation.add(Random.nextIntegerInRange(0, dimensions));
  224. if(!success) i--; //can be add up to some series long loops if maximumAmountOfMutatedBits get closed to problemsize.
  225. }
  226. //console.println(mutationLocation.toString());
  227. return mutationLocation;
  228. }
  229. /**
  230. * Class to represent a Particle.
  231. */
  232. private class Particle{
  233. /**
  234. * The velocity of a particle.
  235. */
  236. public List<Double> velocity;
  237. /**
  238. * The positions genotype.
  239. */
  240. public List<Double> xGenotype;
  241. /**
  242. * The positions phenotype. Alias the current position.
  243. */
  244. public List<Boolean> xPhenotype;
  245. public Individual localBest;
  246. Particle(List<Boolean> position){
  247. this.xPhenotype = position;
  248. //Init velocity, xGenotype with 0.0 values.
  249. this.velocity = position.stream().map(bool -> 0.0).collect(Collectors.toList());
  250. this.xGenotype = position.stream().map(bool -> 0.0).collect(Collectors.toList());
  251. localBest = new Individual();
  252. localBest.fitness = Double.MAX_VALUE;
  253. }
  254. public void checkNewEvaluationValue(double newEvaluationValue) {
  255. if(newEvaluationValue < localBest.fitness) {
  256. localBest.fitness = newEvaluationValue;
  257. localBest.position = xPhenotype.stream().map(bool -> bool).collect(Collectors.toList());
  258. }
  259. }
  260. public String toString() {
  261. return "Particle with xPhenotype(Position), xGenotype, velocity:["
  262. + listToString(xPhenotype) + "],[" + listToString(xGenotype) + "],["
  263. + listToString(velocity) + "]";
  264. }
  265. private <Type> String listToString(List<Type> list) {
  266. return list.stream().map(Object::toString).collect(Collectors.joining(", "));
  267. }
  268. }
  269. }