/** * dMOPSO.java * * @version 1.0 */ package jmetal.metaheuristics.dmopso; import jmetal.core.Algorithm; import jmetal.core.Problem; import jmetal.core.Solution; import jmetal.core.SolutionSet; import jmetal.qualityIndicator.Hypervolume; import jmetal.qualityIndicator.QualityIndicator; import jmetal.util.JMException; import jmetal.util.PseudoRandom; import jmetal.util.wrapper.XReal; import java.io.*; import java.util.StringTokenizer; import java.util.Vector; public class dMOPSO extends Algorithm { //static double y2; //static int use_last = 0; /** * Stores the number of particles_ used */ private int swarmSize_; /** * Stores the maximum Age of each particle before reset */ private int maxAge_; /** * Stores the maximum number of iteration_ */ private int maxIterations_; /** * Stores the current number of iteration_ */ private int iteration_; /** * Stores the particles */ private SolutionSet particles_; /** * Stores the best_ solutions founds so far for each particles */ private Solution[] lBest_; /** * Stores the global best solutions founds so far for each particles */ private Solution[] gBest_; private int[] shfGBest_; /** * Stores the speed_ of each particle */ private double[][] speed_; /** * Stores the age_ of each particle */ private int[] age_; /////// BEGIN MOEAD ////// /** * Z vector (ideal point) */ double[] z_; /** * Lambda vectors */ double[][] lambda_; Solution[] indArray_; String functionType_ = "_PBI";//"_PBI";//"_TCHE";//"_AGG"; String dataDirectory_ ; /////// END MOEAD ////// QualityIndicator indicators_; // QualityIndicator object double r1Max_; double r1Min_; double r2Max_; double r2Min_; double C1Max_; double C1Min_; double C2Max_; double C2Min_; double WMax_; double WMin_; double ChVel1_; double ChVel2_; private double trueHypervolume_; private Hypervolume hy_; private SolutionSet trueFront_; private double deltaMax_[]; private double deltaMin_[]; public dMOPSO(Problem problem) { super(problem); r1Max_ = 1.0; r1Min_ = 0.0; r2Max_ = 1.0; r2Min_ = 0.0; C1Max_ = 2.5; C1Min_ = 1.5; C2Max_ = 2.5; C2Min_ = 1.5; WMax_ = 0.4; WMin_ = 0.1; ChVel1_ = -1.0; ChVel2_ = -1.0; } public dMOPSO(Problem problem, Vector<Double> variables, String trueParetoFront) throws FileNotFoundException { super(problem); r1Max_ = variables.get(0); r1Min_ = variables.get(1); r2Max_ = variables.get(2); r2Min_ = variables.get(3); C1Max_ = variables.get(4); C1Min_ = variables.get(5); C2Max_ = variables.get(6); C2Min_ = variables.get(7); WMax_ = variables.get(8); WMin_ = variables.get(9); ChVel1_ = variables.get(10); ChVel2_ = variables.get(11); hy_ = new Hypervolume(); jmetal.qualityIndicator.util.MetricsUtil mu = new jmetal.qualityIndicator.util.MetricsUtil(); trueFront_ = mu.readNonDominatedSolutionSet(trueParetoFront); trueHypervolume_ = hy_.hypervolume(trueFront_.writeObjectivesToMatrix(), trueFront_.writeObjectivesToMatrix(), problem_.getNumberOfObjectives()); } // dMOPSO /** * Initialize all parameter of the algorithm */ public void initParams() { swarmSize_ = ((Integer) getInputParameter("swarmSize")).intValue(); maxIterations_ = ((Integer) getInputParameter("maxIterations")).intValue(); maxAge_ = ((Integer) getInputParameter("maxAge")).intValue(); indicators_ = (QualityIndicator) getInputParameter("indicators"); String funcType = ((String) getInputParameter("functionType")); if(funcType != null && funcType != ""){ functionType_ = funcType; } iteration_ = 0 ; particles_ = new SolutionSet(swarmSize_); lBest_ = new Solution[swarmSize_]; gBest_ = new Solution[swarmSize_]; shfGBest_ = new int[swarmSize_]; // Create the speed_ vector speed_ = new double[swarmSize_][problem_.getNumberOfVariables()]; age_ = new int[swarmSize_]; deltaMax_ = new double[problem_.getNumberOfVariables()]; deltaMin_ = new double[problem_.getNumberOfVariables()]; for (int i = 0; i < problem_.getNumberOfVariables(); i++) { deltaMax_[i] = (problem_.getUpperLimit(i) - problem_.getLowerLimit(i)) / 2.0; deltaMin_[i] = -deltaMax_[i]; } // for } // initParams // Adaptive inertia private double inertiaWeight(int iter, int miter, double wma, double wmin) { //return - (((wma-wmin)*(double)iter)/(double)miter); return wma; } // inertiaWeight // constriction coefficient (M. Clerc) private double constrictionCoefficient(double c1, double c2) { double rho = c1 + c2; //rho = 1.0 ; if (rho <= 4) { return 1.0; } else { return 2 / (2 - rho - Math.sqrt(Math.pow(rho, 2.0) - 4.0 * rho)); } } // constrictionCoefficient // velocity bounds private double velocityConstriction(double v, double[] deltaMax, double[] deltaMin, int variableIndex, int particleIndex) throws IOException { double result; double dmax = deltaMax[variableIndex]; double dmin = deltaMin[variableIndex]; result = v; if (v > dmax) { result = dmax; } if (v < dmin) { result = dmin; } return result; } // velocityConstriction /** * Update the speed of each particle * @throws JMException */ private void computeSpeed(int i) throws JMException{ double r1, r2, W, C1, C2; double wmax, wmin; XReal particle = new XReal(particles_.get(i)) ; XReal bestParticle = new XReal(lBest_[i]) ; //XReal bestGlobal = new XReal(gBest_[i]) ; XReal bestGlobal = new XReal(gBest_[shfGBest_[i]]) ; r1 = PseudoRandom.randDouble(r1Min_, r1Max_); r2 = PseudoRandom.randDouble(r2Min_, r2Max_); C1 = PseudoRandom.randDouble(C1Min_, C1Max_); C2 = PseudoRandom.randDouble(C2Min_, C2Max_); W = PseudoRandom.randDouble(WMin_, WMax_); wmax = WMax_; wmin = WMin_; for (int var = 0; var < particle.size(); var++) { //Computing the velocity of this particle try { speed_[i][var] = velocityConstriction(constrictionCoefficient(C1, C2) * (inertiaWeight(iteration_, maxIterations_, wmax, wmin) * speed_[i][var] + C1 * r1 * (bestParticle.getValue(var) - particle.getValue(var)) + C2 * r2 * (bestGlobal.getValue(var) - particle.getValue(var))), deltaMax_, deltaMin_, var, i) ; } catch (IOException e) { e.printStackTrace(); } } } // computeSpeed /** * Update the position of each particle * @throws JMException */ private void computeNewPositions(int i) throws JMException { XReal particle = new XReal(particles_.get(i)) ; for (int var = 0; var < particle.size(); var++) { particle.setValue(var, particle.getValue(var) + speed_[i][var]) ; } } // computeNewPositions /** * Runs of the dMOPSO algorithm. * @return a <code>SolutionSet</code> that is a set of non dominated solutions * as a result of the algorithm execution * @throws JMException */ public SolutionSet execute() throws JMException, ClassNotFoundException { //->Step 1.1 Initialize parameters (iteration_ = 0) initParams(); //->Step 1.3 Generate a swarm of N random particles for (int i = 0; i < swarmSize_; i++) { Solution particle = new Solution(problem_); problem_.evaluate(particle); particles_.add(particle); } //-> Step 1.4 Initialize the speed_ and age_ of each particle to 0 for (int i = 0; i < swarmSize_; i++) { for (int j = 0; j < problem_.getNumberOfVariables(); j++) { speed_[i][j] = 0.0; } age_[i] = 0; } /////// BEGIN MOEAD ////// indArray_ = new Solution[problem_.getNumberOfObjectives()]; z_ = new double[problem_.getNumberOfObjectives()]; lambda_ = new double[swarmSize_][problem_.getNumberOfObjectives()]; //-> Step 1.2 Generate a well-distributed set of N weighted vectors initUniformWeight(); initIdealPoint(); /////// END MOEAD ////// //-> Step 1.5 and 1.6 Define the personal best and the global best for (int i = 0; i < particles_.size(); i++) { Solution particle = new Solution(particles_.get(i)); lBest_[i] = particle; gBest_[i] = particle; } updateGlobalBest(); // Iterations ... while (iteration_ < maxIterations_) { //-> Step 2 Suffle the global best shuffleGlobalBest(); //-> Step 3 The cycle for (int i = 0; i < particles_.size(); i++) { if(age_[i] < maxAge_){ //-> Step 3.1 Update particle updateParticle(i); }else{ //-> Step 3.2 Reset particle resetParticle(i); } //-> Step 3.3 Repair bounds repairBounds(i); //-> Step 3.4 Evaluate the particle and update Z* problem_.evaluate(particles_.get(i)); updateReference(particles_.get(i)); //-> Step 3.5 Update the personal best updateLocalBest(i); } //-> Step 4 Update the global best updateGlobalBest(); iteration_++; } SolutionSet ss = new SolutionSet(gBest_.length); for (int i =0; i < gBest_.length; i++) { ss.add(gBest_[i]); } return ss; } // execute // public SolutionSet execute() throws JMException, ClassNotFoundException { // //->Step 1.1 Initialize parameters (iteration_ = 0) // initParams(); // // //->Step 1.3 Generate a swarm of N random particles // for (int i = 0; i < swarmSize_; i++) { // Solution particle = new Solution(problem_); // problem_.evaluate(particle); // particles_.add(particle); // } // // //-> Step 1.4 Initialize the speed_ and age_ of each particle to 0 // for (int i = 0; i < swarmSize_; i++) { // for (int j = 0; j < problem_.getNumberOfVariables(); j++) { // speed_[i][j] = 0.0; // } // age_[i] = 0; // } // // /////// BEGIN MOEAD ////// // indArray_ = new Solution[problem_.getNumberOfObjectives()]; // z_ = new double[problem_.getNumberOfObjectives()]; // lambda_ = new double[swarmSize_][problem_.getNumberOfObjectives()]; // // //-> Step 1.2 Generate a well-distributed set of N weighted vectors // initUniformWeight(); // initIdealPoint(); // /////// END MOEAD ////// // // //-> Step 1.5 and 1.6 Define the personal best and the global best // for (int i = 0; i < particles_.size(); i++) { // Solution particle = new Solution(particles_.get(i)); // lBest_[i] = particle; // gBest_[i] = particle; // //updateGlobalBest(i); // } // updateGlobalBest(); // // //BORRAR // particles_.printObjectivesToFile("EXEC/FUN"+iteration_); // SolutionSet sgb = new SolutionSet(particles_.size()); // for (int i =0; i < gBest_.length; i++) { // sgb.add(gBest_[i]); // } // sgb.printObjectivesToFile("EXEC/GB"+iteration_); // // // Iterations ... // while (iteration_ < maxIterations_) { // // // //-> Step 2 Suffle the global best // shuffleGlobalBest(); // // //-> Step 3 The cycle // for (int i = 0; i < particles_.size(); i++) { // // if(age_[i] < maxAge_){ // //-> Step 3.1 Update particle // updateParticle(i); // }else{ // //-> Step 3.2 Reset particle // resetParticle(i); // } // // //-> Step 3.3 Repair bounds // repairBounds(i); // // //-> Step 3.4 Evaluate the particle and update Z* // problem_.evaluate(particles_.get(i)); // updateReference(particles_.get(i)); // // //-> Step 3.5 Update the personal best // updateLocalBest(i); // //updateGlobalBest(i); // } // // //-> Step 4 Update the global best // updateGlobalBest(); // iteration_++; // //BORRAR // particles_.printObjectivesToFile("EXEC/FUN"+iteration_); // sgb = new SolutionSet(particles_.size()); // for (int i =0; i < gBest_.length; i++) { // sgb.add(gBest_[i]); // } // sgb.printObjectivesToFile("EXEC/GB"+iteration_); // } // // SolutionSet ss = new SolutionSet(gBest_.length); // for (int i =0; i < gBest_.length; i++) { // ss.add(gBest_[i]); // } // // return ss; // } // execute // private void shuffleGlobalBest(){ // Solution[] aux = new Solution[swarmSize_]; // int rnd; // Solution tmp; // // for (int i = 0; i < swarmSize_; i++) // { // aux[i] = new Solution(gBest_[i]); // } // // for (int i = 0; i < swarmSize_; i++) // { // rnd = PseudoRandom.randInt(i, swarmSize_ - 1); // tmp = new Solution(aux[rnd]); // aux[rnd] = new Solution(aux[i]); // gBest_[i] = new Solution(tmp); // } // } // shuffleGlobalBest private void shuffleGlobalBest(){ int[] aux = new int[swarmSize_]; int rnd; int tmp; for (int i = 0; i < swarmSize_; i++) { aux[i] = i; } for (int i = 0; i < swarmSize_; i++) { rnd = PseudoRandom.randInt(i, swarmSize_ - 1); tmp = aux[rnd]; aux[rnd] = aux[i]; shfGBest_[i] = tmp; } } // shuffleGlobalBest private void repairBounds(int part) throws JMException{ XReal particle = new XReal(particles_.get(part)) ; for(int var = 0; var < particle.getNumberOfDecisionVariables(); var++){ if (particle.getValue(var) < problem_.getLowerLimit(var)) { particle.setValue(var, problem_.getLowerLimit(var)); speed_[part][var] = speed_[part][var] * ChVel1_; } if (particle.getValue(var) > problem_.getUpperLimit(var)) { particle.setValue(var, problem_.getUpperLimit(var)); speed_[part][var] = speed_[part][var] * ChVel2_; } } } // repairBounds private void resetParticle(int i) throws JMException { XReal particle = new XReal(particles_.get(i)) ; double mean, sigma, N; for (int var = 0; var < particle.size(); var++) { XReal gB, pB; //gB = new XReal(gBest_[i]); gB = new XReal(gBest_[shfGBest_[i]]); pB = new XReal(lBest_[i]); mean = (gB.getValue(var) - pB.getValue(var))/2; sigma = Math.abs(gB.getValue(var) - pB.getValue(var)); java.util.Random rnd = new java.util.Random(); N = rnd.nextGaussian()*sigma + mean; // N(mean, sigma) //N = box_muller(mean, sigma); particle.setValue(var,N); speed_[i][var] = 0.0; } } // resetParticle /******************************************/ // double box_muller(double m, double s) // { // /* mean m, standard deviation s */ // double x1, x2, w, y1; // // RandomGenerator rnd = new RandomGenerator(); // // if (use_last!=0) /* use value from previous call */ // { // y1 = y2; // use_last = 0; // } // else // { // do // { // x1 = 2.0 * rnd.randomperc() - 1.0; // x2 = 2.0 * rnd.randomperc() - 1.0; // w = x1 * x1 + x2 * x2; // } while (w >= 1.0); // // w = Math.sqrt((-2.0 * Math.log(w)) / w); // y1 = x1 * w; // y2 = x2 * w; // use_last = 1; // } // return (m + y1 * s); // } /******************************************/ private void updateParticle(int i) throws JMException { computeSpeed(i); computeNewPositions(i); } /** * initUniformWeight */ private void initUniformWeight() { if ((problem_.getNumberOfObjectives() == 2) && (swarmSize_ < 300)) { for (int n = 0; n < swarmSize_; n++) { double a = 1.0 * n / (swarmSize_ - 1); lambda_[n][0] = a; lambda_[n][1] = 1 - a; } // for } // if else { String dataFileName; // dataDirectory_ = "/home/juanjo/Dropbox/jMetalDropboxJuanjo/MOEAD_parameters/Weight"; dataDirectory_ = "/Users/antelverde/Softw/pruebas/data/MOEAD_parameters/Weight"; // dataDirectory_ = "/home/jorgero/moead/weight"; dataFileName = "W" + problem_.getNumberOfObjectives() + "D_" + swarmSize_ + ".dat"; // System.out.println(dataDirectory_); // System.out.println(dataDirectory_ + "/" + dataFileName); try { // Open the file FileInputStream fis = new FileInputStream(dataDirectory_ + "/" + dataFileName); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); int i = 0; int j = 0; String aux = br.readLine(); while (aux != null) { StringTokenizer st = new StringTokenizer(aux); j = 0; while (st.hasMoreTokens()) { double value = (new Double(st.nextToken())).doubleValue(); lambda_[i][j] = value; //System.out.println("lambda["+i+","+j+"] = " + value) ; j++; } aux = br.readLine(); i++; } br.close(); } catch (Exception e) { System.out.println("initUniformWeight: failed when reading for file: " + dataDirectory_ + "/" + dataFileName); e.printStackTrace(); } } // else } // initUniformWeight private void initIdealPoint() throws JMException, ClassNotFoundException { for (int i = 0; i < problem_.getNumberOfObjectives(); i++) { z_[i] = 1.0e+30; indArray_[i] = new Solution(problem_); problem_.evaluate(indArray_[i]); } // for for (int i = 0; i < swarmSize_; i++) { updateReference(particles_.get(i)); } // for } // initIdealPoint private void updateReference(Solution individual) { for (int n = 0; n < problem_.getNumberOfObjectives(); n++) { if (individual.getObjective(n) < z_[n]) { z_[n] = individual.getObjective(n); indArray_[n] = new Solution(individual); } } } // updateReference private void updateGlobalBest() { double gBestFitness ; for(int j = 0; j<lambda_.length; j++){ gBestFitness = fitnessFunction(gBest_[j], lambda_[j]) ; for (int i = 0 ; i < particles_.size(); i++) { double v1 = fitnessFunction(particles_.get(i), lambda_[j]) ; double v2 = gBestFitness ; if (v1 < v2) { gBest_[j] = new Solution(particles_.get(i)) ; gBestFitness = v1; } } } } private void updateLocalBest(int part) { double f1, f2; Solution indiv = new Solution(particles_.get(part)); f1 = fitnessFunction(lBest_[part], lambda_[part]); f2 = fitnessFunction(indiv, lambda_[part]); // System.out.println("F1 = "+f1); // System.out.println("F2 = "+f2); if(age_[part] >= maxAge_ || f2 <= f1){ lBest_[part] = indiv; age_[part] = 0; }else{ age_[part]++; } } // updateLocalBest private double fitnessFunction(Solution sol, double[] lambda){ double fitness = 0.0; if (functionType_.equals("_TCHE")) { double maxFun = -1.0e+30; for (int n = 0; n < problem_.getNumberOfObjectives(); n++) { double diff = Math.abs(sol.getObjective(n) - z_[n]); double feval; if (lambda[n] == 0) { feval = 0.0001 * diff; } else { feval = diff * lambda[n]; } if (feval > maxFun) { maxFun = feval; } } // for fitness = maxFun; }else if(functionType_.equals("_AGG")){ double sum = 0.0; for (int n = 0; n < problem_.getNumberOfObjectives(); n++) { sum += (lambda[n]) * sol.getObjective(n); } fitness = sum; }else if(functionType_.equals("_PBI")){ double d1, d2, nl; double theta = 5.0; d1 = d2 = nl = 0.0; for (int i = 0; i < problem_.getNumberOfObjectives(); i++) { d1 += (sol.getObjective(i) - z_[i]) * lambda[i]; nl += Math.pow(lambda[i], 2.0); } nl = Math.sqrt(nl); d1 = Math.abs(d1) / nl; for (int i = 0; i < problem_.getNumberOfObjectives(); i++) { d2 += Math.pow((sol.getObjective(i) - z_[i]) - d1 * (lambda[i] / nl), 2.0); } d2 = Math.sqrt(d2); fitness = (d1 + theta * d2); }else{ System.out.println("dMOPSO.fitnessFunction: unknown type " + functionType_); System.exit(-1); } return fitness; } // fitnessFunction } // dMOPSO