// NonUniformMutation.java // // Author: // Antonio J. Nebro <antonio@lcc.uma.es> // Juan J. Durillo <durillo@lcc.uma.es> // // Copyright (c) 2011 Antonio J. Nebro, Juan J. Durillo // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. package jmetal.operators.mutation; import jmetal.core.Solution; import jmetal.encodings.solutionType.ArrayRealSolutionType; import jmetal.encodings.solutionType.RealSolutionType; import jmetal.util.Configuration; import jmetal.util.JMException; import jmetal.util.PseudoRandom; import jmetal.util.wrapper.XReal; import java.util.Arrays; import java.util.HashMap; import java.util.List; /** * This class implements a non-uniform mutation operator. */ public class NonUniformMutation extends Mutation{ /** * Valid solution types to apply this operator */ private static final List VALID_TYPES = Arrays.asList(RealSolutionType.class, ArrayRealSolutionType.class) ; /** * perturbation_ stores the perturbation value used in the Non Uniform * mutation operator */ private Double perturbation_ = null; /** * maxIterations_ stores the maximun number of iterations. */ private Integer maxIterations_ = null; /** * currentIteration_ stores the iteration in which the operator is going to be * applied */ private Integer currentIteration_ = null; private Double mutationProbability_ = null; /** * Constructor * Creates a new instance of the non uniform mutation */ public NonUniformMutation(HashMap<String, Object> parameters) { super(parameters) ; if (parameters.get("probability") != null) mutationProbability_ = (Double) parameters.get("probability") ; if (parameters.get("perturbation") != null) perturbation_ = (Double) parameters.get("perturbation") ; if (parameters.get("maxIterations") != null) maxIterations_ = (Integer) parameters.get("maxIterations") ; } // NonUniformMutation /** * Constructor * Creates a new instance of the non uniform mutation */ //public NonUniformMutation(Properties properties){ // this(); //} // NonUniformMutation /** * Perform the mutation operation * @param probability Mutation probability * @param solution The solution to mutate * @throws JMException */ public void doMutation(double probability, Solution solution) throws JMException { XReal x = new XReal(solution) ; for (int var = 0; var < solution.getDecisionVariables().length; var++) { if (PseudoRandom.randDouble() < probability) { double rand = PseudoRandom.randDouble(); double tmp; if (rand <= 0.5) { tmp = delta(x.getUpperBound(var) - x.getValue(var), perturbation_.doubleValue()); tmp += x.getValue(var); } else { tmp = delta(x.getLowerBound(var) - x.getValue(var), perturbation_.doubleValue()); tmp += x.getValue(var); } if (tmp < x.getLowerBound(var)) tmp = x.getLowerBound(var); else if (tmp > x.getUpperBound(var)) tmp = x.getUpperBound(var); x.setValue(var, tmp) ; } } } // doMutation /** * Calculates the delta value used in NonUniform mutation operator */ private double delta(double y, double bMutationParameter) { double rand = PseudoRandom.randDouble(); int it,maxIt; it = currentIteration_.intValue(); maxIt = maxIterations_.intValue(); return (y * (1.0 - Math.pow(rand, Math.pow((1.0 - it /(double) maxIt),bMutationParameter) ))); } // delta /** * Executes the operation * @param object An object containing a solution * @return An object containing the mutated solution * @throws JMException */ public Object execute(Object object) throws JMException { Solution solution = (Solution)object; if (!VALID_TYPES.contains(solution.getType().getClass())) { Configuration.logger_.severe("NonUniformMutation.execute: the solution " + solution.getType() + "is not of the right type"); Class cls = java.lang.String.class; String name = cls.getName(); throw new JMException("Exception in " + name + ".execute()") ; } // if if (getParameter("currentIteration") != null) currentIteration_ = (Integer) getParameter("currentIteration") ; doMutation(mutationProbability_,solution); return solution; } // execute } // NonUniformMutation