// PolynomialBitFlipMutation.java
//
// Author:
// Antonio J. Nebro <antonio@lcc.uma.es>
//
// Copyright (c) 2011 Antonio J. Nebro
//
// 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.ArrayRealAndBinarySolutionType;
import jmetal.encodings.variable.Binary;
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;
public class PolynomialBitFlipMutation extends Mutation {
private static final double ETA_M_DEFAULT_ = 20.0;
private final double eta_m_=ETA_M_DEFAULT_;
private Double realMutationProbability_ = null ;
private Double binaryMutationProbability_ = null ;
private double distributionIndex_ = eta_m_;
/**
* Valid solution types to apply this operator
*/
private static final List VALID_TYPES = Arrays.asList(ArrayRealAndBinarySolutionType.class) ;
/**
* Constructor
*/
public PolynomialBitFlipMutation(HashMap<String, Object> parameters) {
super(parameters) ;
if (parameters.get("realMutationProbability") != null)
realMutationProbability_ = (Double) parameters.get("realMutationProbability") ;
if (parameters.get("binaryMutationProbability") != null)
binaryMutationProbability_ = (Double) parameters.get("binaryMutationProbability") ;
if (parameters.get("distributionIndex") != null)
distributionIndex_ = (Double) parameters.get("distributionIndex") ;
} // PolynomialBitFlipMutation
@Override
public Object execute(Object object) throws JMException {
Solution solution = (Solution)object;
if (!VALID_TYPES.contains(solution.getType().getClass())) {
Configuration.logger_.severe("PolynomialBitFlipMutation.execute: the solution " +
"type " + solution.getType() + " is not allowed with this operator");
Class cls = java.lang.String.class;
String name = cls.getName();
throw new JMException("Exception in " + name + ".execute()") ;
} // if
doMutation(realMutationProbability_, binaryMutationProbability_,solution);
return solution;
} // execute
/**
* doMutation method
* @param realProbability
* @param binaryProbability
* @param solution
* @throws JMException
*/
public void doMutation(Double realProbability, Double binaryProbability, Solution solution) throws JMException {
double rnd, delta1, delta2, mut_pow, deltaq;
double y, yl, yu, val, xy;
XReal x = new XReal(solution) ;
Binary binaryVariable = (Binary)solution.getDecisionVariables()[1] ;
// Polynomial mutation applied to the array real
for (int var=0; var < x.size(); var++) {
if (PseudoRandom.randDouble() <= realProbability) {
y = x.getValue(var);
yl = x.getLowerBound(var);
yu = x.getUpperBound(var);
delta1 = (y-yl)/(yu-yl);
delta2 = (yu-y)/(yu-yl);
rnd = PseudoRandom.randDouble();
mut_pow = 1.0/(eta_m_+1.0);
if (rnd <= 0.5)
{
xy = 1.0-delta1;
val = 2.0*rnd+(1.0-2.0*rnd)*(Math.pow(xy,(distributionIndex_+1.0)));
deltaq = java.lang.Math.pow(val,mut_pow) - 1.0;
}
else
{
xy = 1.0-delta2;
val = 2.0*(1.0-rnd)+2.0*(rnd-0.5)*(java.lang.Math.pow(xy,(distributionIndex_+1.0)));
deltaq = 1.0 - (java.lang.Math.pow(val,mut_pow));
}
y = y + deltaq*(yu-yl);
if (y<yl)
y = yl;
if (y>yu)
y = yu;
x.setValue(var, y);
} // if
} // for
// BitFlip mutation applied to the binary part
for (int i = 0; i < binaryVariable.getNumberOfBits(); i++)
if (PseudoRandom.randDouble() < binaryProbability)
binaryVariable.bits_.flip(i) ;
} // doMutation
} // PolynomialBitFlipMutation