SimplePSO.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. package psoAlgoCode;
  2. import java.util.Random;
  3. import java.util.Vector;
  4. import ui.controller.Control;
  5. import ui.model.Model;
  6. public class SimplePSO {
  7. // Random factors for calculations with "doubles"
  8. private double D1;
  9. private double D2;
  10. private boolean B1;
  11. private boolean B2;
  12. // New BPSO
  13. private double R1;
  14. private double R2;
  15. private double w;
  16. private double phi;
  17. private double c1;
  18. private double c2;
  19. private double rmu;
  20. // Function to be used
  21. private Function f;
  22. private int iterations;
  23. private Swarm swarm = new Swarm();
  24. private Random random = new Random();
  25. public SimplePSO(Model model, Control control, Coordinate<Vector<Object>> startPos) {
  26. iterations = 0;
  27. if (startPos == null) {
  28. Constants.setDimensions(10);
  29. } else {
  30. Constants.setDimensions(startPos.getCoords().size());
  31. }
  32. f = new Function();
  33. }
  34. /**
  35. * Initiate the swarm with random values depending on the type of calculate
  36. * (boolean or doubles)
  37. */
  38. /*private void initSwarmRandom() {
  39. for (int i = 0; i < Constants.SWARM_SIZE; i++) {
  40. Particle p = new Particle(Constants.DIMENSIONS);
  41. Coordinate<Vector<Object>> tempPos = new Coordinate<Vector<Object>>();
  42. Coordinate<Vector<Object>> tempVel = new Coordinate<Vector<Object>>();
  43. for (int j = 0; j < Constants.DIMENSIONS; j++) {
  44. tempPos.setCoord(RandomFunctions.nextDoubles(1), j);
  45. tempVel.setCoord(RandomFunctions.nextDoubles(1), j);
  46. }
  47. p.setPositionAdv(tempPos);
  48. p.setVelocityAdv(tempVel);
  49. swarm.addMember(p);
  50. }
  51. initCoeff();
  52. }*/
  53. private void initSwarm(Coordinate<Vector<Object>> startPos) {
  54. for (int i = 0; i < Constants.SWARM_SIZE; i++) {
  55. Particle p = new Particle(Constants.DIMENSIONS);
  56. Coordinate<Vector<Object>> tempPos = new Coordinate<Vector<Object>>();
  57. Coordinate<Vector<Object>> tempVel = new Coordinate<Vector<Object>>();
  58. for (int j = 0; j < Constants.DIMENSIONS; j++) {
  59. int dim = startPos.getCoord(j).size();
  60. tempPos.setCoord(RandomFunctions.nextBoolean(dim), j);
  61. tempVel.setCoord(RandomFunctions.nextRandoms(dim), j);
  62. }
  63. p.setPositionAdv(tempPos);
  64. p.setVelocityAdv(tempVel);
  65. swarm.addMember(p);
  66. }
  67. initCoeff();
  68. }
  69. private void runFunction(Model model, Control control) {
  70. for (int i = 0; i < Constants.SWARM_SIZE; i++) {
  71. swarm.getSwarm().get(i).setActualValue(f.execute(swarm.getSwarm().get(i), i + 1, model, control));
  72. }
  73. }
  74. private void initCoeff() {
  75. // Coefficients for the calculation of velocity after S. Lee
  76. phi = Constants.PHI;
  77. rmu = Constants.RMU;
  78. w = 1 / ((phi - 1) + Math.sqrt(Math.pow(phi, 2) - 2 * phi));
  79. c1 = phi * w;
  80. c2 = c1;
  81. }
  82. public void caclSimplePSO(Model model, Control control, Coordinate<Vector<Object>> startPos) {
  83. initSwarm(startPos);
  84. runFunction(model, control);
  85. evaluate();
  86. while (iterations <= Constants.MAX_ITERATION) {
  87. for (int i = 0; i < Constants.SWARM_SIZE; i++) {
  88. Particle temp = swarm.getSwarm().get(i);
  89. // Binary PSO 2 (S. Lee)
  90. // Update Velocity
  91. temp.setVelocityAdv(updateNewVelAdv(temp.getVelocityAdv(), temp.getPositionAdv(),
  92. temp.getBestLocalPosAdv(), iterations));
  93. // Update Position
  94. temp.setPositionAdv(updateNewPosAdv(temp.getVelocityAdv(), temp.getPositionAdv()));
  95. // Mutation Position
  96. temp.setPositionAdv(mutatePos(temp.getPositionAdv()));
  97. // Decode Position
  98. temp.setPositionAdv(decodePos(temp.getPositionAdv()));
  99. //System.out.println("calculated centroid: " + swarm.calculateSwarmCentroid().toString());
  100. // Uncomment this two line and change the init of Vel to nextBoolean(dim) ->
  101. // binary PSO 1
  102. // temp.setVelocityAdv(updateVelAdv(temp.getVelocityAdv(),
  103. // temp.getPositionAdv(),
  104. // temp.getBestLocalPosAdv(), iterations));
  105. // temp.setPositionAdv(updatePosAdv(temp.getVelocityAdv(),
  106. // temp.getPositionAdv()));
  107. }
  108. // plotSwarm();
  109. iterations++;
  110. runFunction(model, control);
  111. evaluate();
  112. }
  113. }
  114. /* public void caclNextItSimplePSO(Model model, Control control, Coordinate<Vector<Object>> startPos) {
  115. initSwarm(startPos);
  116. runFunction(model, control);
  117. evaluate();
  118. for (int i = 0; i < Constants.SWARM_SIZE; i++) {
  119. Particle temp = swarm.getSwarm().get(i);
  120. // Update Velocity
  121. temp.setVelocityAdv(updateNewVelAdv(temp.getVelocityAdv(), temp.getPositionAdv(), temp.getBestLocalPosAdv(),
  122. iterations));
  123. // Update Position
  124. temp.setPositionAdv(updateNewPosAdv(temp.getVelocityAdv(), temp.getPositionAdv()));
  125. // Mutation Position
  126. temp.setPositionAdv(mutatePos(temp.getPositionAdv()));
  127. // Decode Position
  128. temp.setPositionAdv(decodePos(temp.getPositionAdv()));
  129. }
  130. System.out.println("calculated centroid: " + swarm.calculateSwarmCentroid().toString());
  131. evaluate();
  132. iterations++;
  133. }*/
  134. /**
  135. * The boolean-based function to update the velocity of a particle depending on
  136. * the inertia, social and cognitive factors. Here is important to consider the
  137. * analogy of the operators.This calculation is based in the binary PSO version
  138. * from S Lee.
  139. *
  140. * @param vel
  141. * @param pos
  142. * @param bestLocal
  143. * @param index
  144. * @return
  145. */
  146. private Coordinate<Vector<Object>> updateNewVelAdv(Coordinate<Vector<Object>> vel, Coordinate<Vector<Object>> pos,
  147. Coordinate<Vector<Object>> bestLocal, int index) {
  148. Coordinate<Vector<Object>> result = new Coordinate<Vector<Object>>();
  149. for (int dim = 0; dim < Constants.DIMENSIONS; dim++) {
  150. Vector<Object> newCoord = new Vector<Object>();
  151. R1 = Math.random();
  152. R2 = Math.random();
  153. for (int i = 0; i < vel.getCoord(dim).size(); i++) {
  154. if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) {
  155. // Random coefficients for the calculation of velocity after S. Lee
  156. double value = 0.0;
  157. value = (w * (double) vel.getCoord(dim).get(i))
  158. + (c1 * R1
  159. * (transformBoolToDouble((boolean) bestLocal.getCoord(dim).get(i))
  160. - transformBoolToDouble((boolean) pos.getCoord(dim).get(i))))
  161. + (c2 * R2
  162. * (transformBoolToDouble(
  163. (boolean) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i))
  164. - transformBoolToDouble((boolean) pos.getCoord(dim).get(i))));
  165. newCoord.add(i, value);
  166. } else if (vel.getCoord(dim).get(i).getClass().equals(Double.class)) {
  167. D1 = random.nextDouble();
  168. D2 = random.nextDouble();
  169. double value = 0.0;
  170. value = getOmega(index) * (double) vel.getCoord(dim).get(i)
  171. + (Constants.ALPHA1 * D1
  172. * ((double) bestLocal.getCoord(dim).get(i) - (double) pos.getCoord(dim).get(i)))
  173. + (Constants.ALPHA2 * D2
  174. * ((double) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i)
  175. - (double) pos.getCoord(dim).get(i)));
  176. newCoord.add(i, value);
  177. }
  178. }
  179. result.setCoord(newCoord, dim);
  180. }
  181. return result;
  182. }
  183. /**
  184. * The boolean-based function to update the position of a particle adding the
  185. * current position with the new velocity (calculated in updateVel(Coordinates
  186. * vel, Coordinates pos, Coordinates bestLocal, int i)). Here is important to
  187. * consider the analogy of the operators. This calculation is based in the
  188. * binary PSO version from S Lee.
  189. *
  190. * @param vel
  191. * the updated velocity
  192. * @param pos
  193. * the current position
  194. * @return the updated position of the particle
  195. */
  196. private Coordinate<Vector<Object>> updateNewPosAdv(Coordinate<Vector<Object>> vel, Coordinate<Vector<Object>> pos) {
  197. Coordinate<Vector<Object>> newPos = new Coordinate<Vector<Object>>();
  198. for (int dim = 0; dim < Constants.DIMENSIONS; dim++) {
  199. Vector<Object> newCoord = new Vector<Object>();
  200. for (int i = 0; i < vel.getCoord(dim).size(); i++) {
  201. if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) {
  202. double value = 0.0;
  203. value = transformBoolToDouble((boolean) pos.getCoord(dim).get(i))
  204. + (double) vel.getCoord(dim).get(i);
  205. newCoord.add(i, value);
  206. }
  207. if (pos.getCoord(dim).get(i).getClass().equals(Double.class)) {
  208. double value = 0.0;
  209. value = (double) pos.getCoord(dim).get(i) + (double) vel.getCoord(dim).get(i);
  210. newCoord.add(i, value);
  211. }
  212. }
  213. newPos.setCoord(newCoord, dim);
  214. }
  215. return newPos;
  216. }
  217. private Coordinate<Vector<Object>> mutatePos(Coordinate<Vector<Object>> pos) {
  218. Coordinate<Vector<Object>> newPos = new Coordinate<Vector<Object>>();
  219. for (int dim = 0; dim < Constants.DIMENSIONS; dim++) {
  220. Vector<Object> newCoord = new Vector<Object>();
  221. for (int i = 0; i < pos.getCoord(dim).size(); i++) {
  222. if (Math.random() < rmu) {
  223. newCoord.add(i, -(double) pos.getCoord(dim).get(i));
  224. } else {
  225. newCoord.add(i, (double) pos.getCoord(dim).get(i));
  226. }
  227. }
  228. newPos.setCoord(newCoord, dim);
  229. }
  230. return newPos;
  231. }
  232. private Coordinate<Vector<Object>> decodePos(Coordinate<Vector<Object>> pos) {
  233. Coordinate<Vector<Object>> newPos = new Coordinate<Vector<Object>>();
  234. for (int dim = 0; dim < Constants.DIMENSIONS; dim++) {
  235. Vector<Object> newCoord = new Vector<Object>();
  236. for (int i = 0; i < pos.getCoord(dim).size(); i++) {
  237. double decoder = sigmoid((double) pos.getCoord(dim).get(i));
  238. if (Math.random() >= decoder) {
  239. newCoord.add(i, true);
  240. } else {
  241. newCoord.add(i, false);
  242. }
  243. }
  244. newPos.setCoord(newCoord, dim);
  245. }
  246. return newPos;
  247. }
  248. private double sigmoid(double input) {
  249. double result = 0.0;
  250. result = 1 / (1 + Math.pow(Math.E, -input));
  251. return result;
  252. }
  253. private void evaluate() {
  254. swarm.updateLocalBestValues();
  255. // Update Global Best
  256. Particle temp_best = getBestValue();
  257. temp_best.updateLocalBest();
  258. if (iterations == 0) {
  259. swarm.setGlobalBest(temp_best);
  260. } else {
  261. swarm.updateGlobalBest(temp_best);
  262. }
  263. swarm.addEleToRecord(swarm.getGlobalBest().getLocalBestValue());
  264. }
  265. private double transformBoolToDouble(boolean input) {
  266. if (input == true) {
  267. return 1.0;
  268. } else {
  269. return 0.0;
  270. }
  271. }
  272. /**
  273. * Calculation of binary XOR operator
  274. *
  275. * @param b1
  276. * Boolean 1
  277. * @param b2
  278. * Boolean 2
  279. * @return b1 XOR b2
  280. */
  281. private Boolean calcXOR(Boolean b1, Boolean b2) {
  282. Boolean result = false;
  283. result = (!b1 && b2) || (b1 && !b2);
  284. return result;
  285. }
  286. public Particle getBestValue() {
  287. Particle temp_particle = swarm.getSwarm().get(0);
  288. temp_particle.setActualValue(swarm.getSwarm().get(0).getActualValue());
  289. for (int i = 1; i < Constants.SWARM_SIZE; i++) {
  290. if (swarm.getSwarm().get(i).getActualValue() < temp_particle.getActualValue()) {
  291. temp_particle = swarm.getSwarm().get(i);
  292. }
  293. }
  294. return temp_particle;
  295. }
  296. public Vector<Double> getGBRecord() {
  297. return swarm.getGlobalBestRecord();
  298. }
  299. public Coordinate<Vector<Object>> getBestConfig() {
  300. Coordinate<Vector<Object>> result = new Coordinate<Vector<Object>>();
  301. result = swarm.getGlobalBest().getBestLocalPosAdv();
  302. return result;
  303. }
  304. public String getNameOfFunc() {
  305. return f.name;
  306. }
  307. /**
  308. * Return the Omega depending the current iteration.
  309. *
  310. * @param ite
  311. * @return
  312. */
  313. public double getOmega(int ite) {
  314. double newOmega = Constants.START_OMEGA - (Constants.DIFF_OMEGA * ite);
  315. return newOmega;
  316. }
  317. public int getIteration() {
  318. return iterations;
  319. }
  320. /*private Coordinate<Vector<Object>> updateVelAdv(Coordinate<Vector<Object>> vel, Coordinate<Vector<Object>> pos,
  321. Coordinate<Vector<Object>> bestLocal, int index) {
  322. Coordinate<Vector<Object>> result = new Coordinate<Vector<Object>>();
  323. for (int dim = 0; dim < Constants.DIMENSIONS; dim++) {
  324. Vector<Object> newCoord = new Vector<Object>();
  325. for (int i = 0; i < vel.getCoord(dim).size(); i++) {
  326. if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) {
  327. boolean omega = random.nextBoolean();
  328. B1 = random.nextBoolean();
  329. B2 = random.nextBoolean();
  330. boolean value = true;
  331. value = (omega && (boolean) vel.getCoord(dim).get(i)) || (B1
  332. && (calcXOR((boolean) bestLocal.getCoord(dim).get(i), (boolean) pos.getCoord(dim).get(i))))
  333. || (B2 && (calcXOR((boolean) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i),
  334. (boolean) pos.getCoord(dim).get(i))));
  335. newCoord.add(i, value);
  336. } else if (vel.getCoord(dim).get(i).getClass().equals(Double.class)) {
  337. D1 = random.nextDouble();
  338. D2 = random.nextDouble();
  339. double value = 0.0;
  340. value = getOmega(index) * (double) vel.getCoord(dim).get(i)
  341. + (Constants.ALPHA1 * D1
  342. * ((double) bestLocal.getCoord(dim).get(i) - (double) pos.getCoord(dim).get(i)))
  343. + (Constants.ALPHA2 * D2
  344. * ((double) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i)
  345. - (double) pos.getCoord(dim).get(i)));
  346. newCoord.add(i, value);
  347. }
  348. }
  349. result.setCoord(newCoord, dim);
  350. }
  351. return result;
  352. }*/
  353. /*private Coordinate<Vector<Object>> updatePosAdv(Coordinate<Vector<Object>> vel, Coordinate<Vector<Object>> pos) {
  354. Coordinate<Vector<Object>> newPos = new Coordinate<Vector<Object>>();
  355. for (int dim = 0; dim < Constants.DIMENSIONS; dim++) {
  356. Vector<Object> newCoord = new Vector<Object>();
  357. for (int i = 0; i < vel.getCoord(dim).size(); i++) {
  358. if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) {
  359. boolean value = false;
  360. value = calcXOR((boolean) pos.getCoord(dim).get(i), (boolean) vel.getCoord(dim).get(i));
  361. newCoord.add(i, value);
  362. }
  363. if (pos.getCoord(dim).get(i).getClass().equals(Double.class)) {
  364. double value = 0.0;
  365. value = (double) pos.getCoord(dim).get(i) + (double) vel.getCoord(dim).get(i);
  366. newCoord.add(i, value);
  367. }
  368. }
  369. newPos.setCoord(newCoord, dim);
  370. }
  371. return newPos;
  372. }*/
  373. }