package psoAlgoCode; import java.util.Random; import java.util.Vector; import ui.controller.Control; import ui.model.Model; public class SimplePSO { // Random factors for calculations with "doubles" private double D1; private double D2; private boolean B1; private boolean B2; // New BPSO private double R1; private double R2; private double w; private double phi; private double c1; private double c2; private double rmu; // Function to be used private Function f; private int iterations; private Swarm swarm = new Swarm(); private Random random = new Random(); public SimplePSO(Model model, Control control, Coordinate> startPos) { iterations = 0; if (startPos == null) { Constants.setDimensions(10); } else { Constants.setDimensions(startPos.getCoords().size()); } f = new Function(); } /** * Initiate the swarm with random values depending on the type of calculate * (boolean or doubles) */ private void initSwarmRandom() { for (int i = 0; i < Constants.SWARM_SIZE; i++) { Particle p = new Particle(Constants.DIMENSIONS); Coordinate> tempPos = new Coordinate>(); Coordinate> tempVel = new Coordinate>(); for (int j = 0; j < Constants.DIMENSIONS; j++) { tempPos.setCoord(RandomFunctions.nextDoubles(1), j); tempVel.setCoord(RandomFunctions.nextDoubles(1), j); } p.setPositionAdv(tempPos); p.setVelocityAdv(tempVel); swarm.addMember(p); } initCoeff(); } private void initSwarm(Coordinate> startPos) { for (int i = 0; i < Constants.SWARM_SIZE; i++) { Particle p = new Particle(Constants.DIMENSIONS); Coordinate> tempPos = new Coordinate>(); Coordinate> tempVel = new Coordinate>(); for (int j = 0; j < Constants.DIMENSIONS; j++) { int dim = startPos.getCoord(j).size(); tempPos.setCoord(RandomFunctions.nextBoolean(dim), j); tempVel.setCoord(RandomFunctions.nextRandoms(dim), j); } p.setPositionAdv(tempPos); p.setVelocityAdv(tempVel); swarm.addMember(p); } initCoeff(); } private void runFunction(Model model, Control control) { for (int i = 0; i < Constants.SWARM_SIZE; i++) { swarm.getSwarm().get(i).setActualValue(f.execute(swarm.getSwarm().get(i), i + 1, model, control)); } } private void initCoeff() { // Coefficients for the calculation of velocity after S. Lee phi = Constants.PHI; rmu = Constants.RMU; w = 1 / ((phi - 1) + Math.sqrt(Math.pow(phi, 2) - 2 * phi)); c1 = phi * w; c2 = c1; } public void caclSimplePSO(Model model, Control control, Coordinate> startPos) { initSwarm(startPos); runFunction(model, control); evaluate(); while (iterations <= Constants.MAX_ITERATION) { for (int i = 0; i < Constants.SWARM_SIZE; i++) { Particle temp = swarm.getSwarm().get(i); // Binary PSO 2 (S. Lee) // Update Velocity temp.setVelocityAdv(updateNewVelAdv(temp.getVelocityAdv(), temp.getPositionAdv(), temp.getBestLocalPosAdv(), iterations)); // Update Position temp.setPositionAdv(updateNewPosAdv(temp.getVelocityAdv(), temp.getPositionAdv())); // Mutation Position temp.setPositionAdv(mutatePos(temp.getPositionAdv())); // Decode Position temp.setPositionAdv(decodePos(temp.getPositionAdv())); //System.out.println("calculated centroid: " + swarm.calculateSwarmCentroid().toString()); // Uncomment this two line and change the init of Vel to nextBoolean(dim) -> // binary PSO 1 // temp.setVelocityAdv(updateVelAdv(temp.getVelocityAdv(), // temp.getPositionAdv(), // temp.getBestLocalPosAdv(), iterations)); // temp.setPositionAdv(updatePosAdv(temp.getVelocityAdv(), // temp.getPositionAdv())); } // plotSwarm(); iterations++; runFunction(model, control); evaluate(); } } public void caclNextItSimplePSO(Model model, Control control, Coordinate> startPos) { initSwarm(startPos); runFunction(model, control); evaluate(); for (int i = 0; i < Constants.SWARM_SIZE; i++) { Particle temp = swarm.getSwarm().get(i); // Update Velocity temp.setVelocityAdv(updateNewVelAdv(temp.getVelocityAdv(), temp.getPositionAdv(), temp.getBestLocalPosAdv(), iterations)); // Update Position temp.setPositionAdv(updateNewPosAdv(temp.getVelocityAdv(), temp.getPositionAdv())); // Mutation Position temp.setPositionAdv(mutatePos(temp.getPositionAdv())); // Decode Position temp.setPositionAdv(decodePos(temp.getPositionAdv())); } System.out.println("calculated centroid: " + swarm.calculateSwarmCentroid().toString()); evaluate(); iterations++; } /** * The boolean-based function to update the velocity of a particle depending on * the inertia, social and cognitive factors. Here is important to consider the * analogy of the operators.This calculation is based in the binary PSO version * from S Lee. * * @param vel * @param pos * @param bestLocal * @param index * @return */ private Coordinate> updateNewVelAdv(Coordinate> vel, Coordinate> pos, Coordinate> bestLocal, int index) { Coordinate> result = new Coordinate>(); for (int dim = 0; dim < Constants.DIMENSIONS; dim++) { Vector newCoord = new Vector(); R1 = Math.random(); R2 = Math.random(); for (int i = 0; i < vel.getCoord(dim).size(); i++) { if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) { // Random coefficients for the calculation of velocity after S. Lee double value = 0.0; value = (w * (double) vel.getCoord(dim).get(i)) + (c1 * R1 * (transformBoolToDouble((boolean) bestLocal.getCoord(dim).get(i)) - transformBoolToDouble((boolean) pos.getCoord(dim).get(i)))) + (c2 * R2 * (transformBoolToDouble( (boolean) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i)) - transformBoolToDouble((boolean) pos.getCoord(dim).get(i)))); newCoord.add(i, value); } else if (vel.getCoord(dim).get(i).getClass().equals(Double.class)) { D1 = random.nextDouble(); D2 = random.nextDouble(); double value = 0.0; value = getOmega(index) * (double) vel.getCoord(dim).get(i) + (Constants.ALPHA1 * D1 * ((double) bestLocal.getCoord(dim).get(i) - (double) pos.getCoord(dim).get(i))) + (Constants.ALPHA2 * D2 * ((double) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i) - (double) pos.getCoord(dim).get(i))); newCoord.add(i, value); } } result.setCoord(newCoord, dim); } return result; } /** * The boolean-based function to update the position of a particle adding the * current position with the new velocity (calculated in updateVel(Coordinates * vel, Coordinates pos, Coordinates bestLocal, int i)). Here is important to * consider the analogy of the operators. This calculation is based in the * binary PSO version from S Lee. * * @param vel * the updated velocity * @param pos * the current position * @return the updated position of the particle */ private Coordinate> updateNewPosAdv(Coordinate> vel, Coordinate> pos) { Coordinate> newPos = new Coordinate>(); for (int dim = 0; dim < Constants.DIMENSIONS; dim++) { Vector newCoord = new Vector(); for (int i = 0; i < vel.getCoord(dim).size(); i++) { if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) { double value = 0.0; value = transformBoolToDouble((boolean) pos.getCoord(dim).get(i)) + (double) vel.getCoord(dim).get(i); newCoord.add(i, value); } if (pos.getCoord(dim).get(i).getClass().equals(Double.class)) { double value = 0.0; value = (double) pos.getCoord(dim).get(i) + (double) vel.getCoord(dim).get(i); newCoord.add(i, value); } } newPos.setCoord(newCoord, dim); } return newPos; } private Coordinate> mutatePos(Coordinate> pos) { Coordinate> newPos = new Coordinate>(); for (int dim = 0; dim < Constants.DIMENSIONS; dim++) { Vector newCoord = new Vector(); for (int i = 0; i < pos.getCoord(dim).size(); i++) { if (Math.random() < rmu) { newCoord.add(i, -(double) pos.getCoord(dim).get(i)); } else { newCoord.add(i, (double) pos.getCoord(dim).get(i)); } } newPos.setCoord(newCoord, dim); } return newPos; } private Coordinate> decodePos(Coordinate> pos) { Coordinate> newPos = new Coordinate>(); for (int dim = 0; dim < Constants.DIMENSIONS; dim++) { Vector newCoord = new Vector(); for (int i = 0; i < pos.getCoord(dim).size(); i++) { double decoder = sigmoid((double) pos.getCoord(dim).get(i)); if (Math.random() >= decoder) { newCoord.add(i, true); } else { newCoord.add(i, false); } } newPos.setCoord(newCoord, dim); } return newPos; } private double sigmoid(double input) { double result = 0.0; result = 1 / (1 + Math.pow(Math.E, -input)); return result; } private void evaluate() { swarm.updateLocalBestValues(); // Update Global Best Particle temp_best = getBestValue(); temp_best.updateLocalBest(); if (iterations == 0) { swarm.setGlobalBest(temp_best); } else { swarm.updateGlobalBest(temp_best); } swarm.addEleToRecord(swarm.getGlobalBest().getLocalBestValue()); } private double transformBoolToDouble(boolean input) { if (input == true) { return 1.0; } else { return 0.0; } } /** * Calculation of binary XOR operator * * @param b1 * Boolean 1 * @param b2 * Boolean 2 * @return b1 XOR b2 */ private Boolean calcXOR(Boolean b1, Boolean b2) { Boolean result = false; result = (!b1 && b2) || (b1 && !b2); return result; } public Particle getBestValue() { Particle temp_particle = swarm.getSwarm().get(0); temp_particle.setActualValue(swarm.getSwarm().get(0).getActualValue()); for (int i = 1; i < Constants.SWARM_SIZE; i++) { if (swarm.getSwarm().get(i).getActualValue() < temp_particle.getActualValue()) { temp_particle = swarm.getSwarm().get(i); } } return temp_particle; } public Vector getGBRecord() { return swarm.getGlobalBestRecord(); } public Coordinate> getBestConfig() { Coordinate> result = new Coordinate>(); result = swarm.getGlobalBest().getBestLocalPosAdv(); return result; } public String getNameOfFunc() { return f.name; } /** * Return the Omega depending the current iteration. * * @param ite * @return */ public double getOmega(int ite) { double newOmega = Constants.START_OMEGA - (Constants.DIFF_OMEGA * ite); return newOmega; } public int getIteration() { return iterations; } private Coordinate> updateVelAdv(Coordinate> vel, Coordinate> pos, Coordinate> bestLocal, int index) { Coordinate> result = new Coordinate>(); for (int dim = 0; dim < Constants.DIMENSIONS; dim++) { Vector newCoord = new Vector(); for (int i = 0; i < vel.getCoord(dim).size(); i++) { if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) { boolean omega = random.nextBoolean(); B1 = random.nextBoolean(); B2 = random.nextBoolean(); boolean value = true; value = (omega && (boolean) vel.getCoord(dim).get(i)) || (B1 && (calcXOR((boolean) bestLocal.getCoord(dim).get(i), (boolean) pos.getCoord(dim).get(i)))) || (B2 && (calcXOR((boolean) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i), (boolean) pos.getCoord(dim).get(i)))); newCoord.add(i, value); } else if (vel.getCoord(dim).get(i).getClass().equals(Double.class)) { D1 = random.nextDouble(); D2 = random.nextDouble(); double value = 0.0; value = getOmega(index) * (double) vel.getCoord(dim).get(i) + (Constants.ALPHA1 * D1 * ((double) bestLocal.getCoord(dim).get(i) - (double) pos.getCoord(dim).get(i))) + (Constants.ALPHA2 * D2 * ((double) swarm.getGlobalBest().getPositionAdv().getCoord(dim).get(i) - (double) pos.getCoord(dim).get(i))); newCoord.add(i, value); } } result.setCoord(newCoord, dim); } return result; } private Coordinate> updatePosAdv(Coordinate> vel, Coordinate> pos) { Coordinate> newPos = new Coordinate>(); for (int dim = 0; dim < Constants.DIMENSIONS; dim++) { Vector newCoord = new Vector(); for (int i = 0; i < vel.getCoord(dim).size(); i++) { if (pos.getCoord(dim).get(i).getClass().equals(Boolean.class)) { boolean value = false; value = calcXOR((boolean) pos.getCoord(dim).get(i), (boolean) vel.getCoord(dim).get(i)); newCoord.add(i, value); } if (pos.getCoord(dim).get(i).getClass().equals(Double.class)) { double value = 0.0; value = (double) pos.getCoord(dim).get(i) + (double) vel.getCoord(dim).get(i); newCoord.add(i, value); } } newPos.setCoord(newCoord, dim); } return newPos; } }