// HUXCrossover.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.crossover; import jmetal.core.Solution; import jmetal.encodings.solutionType.BinaryRealSolutionType; import jmetal.encodings.solutionType.BinarySolutionType; import jmetal.encodings.variable.Binary; import jmetal.util.Configuration; import jmetal.util.JMException; import jmetal.util.PseudoRandom; import java.util.Arrays; import java.util.HashMap; import java.util.List; /** * This class allows to apply a HUX crossover operator using two parent * solutions. * NOTE: the operator is applied to the first encodings.variable of the solutions, and * the type of the solutions must be Binary or BinaryReal */ public class HUXCrossover extends Crossover{ /** * Valid solution types to apply this operator */ private static final List VALID_TYPES = Arrays.asList(BinarySolutionType.class, BinaryRealSolutionType.class) ; private Double probability_ = null ; /** * Constructor * Create a new instance of the HUX crossover operator. */ public HUXCrossover(HashMap<String, Object> parameters) { super(parameters) ; if (parameters.get("probability") != null) probability_ = (Double) parameters.get("probability") ; } // HUXCrossover /** * Constructor * Create a new intance of the HUX crossover operator. */ //public HUXCrossover(Properties properties) { // this(); //} // HUXCrossover /** * Perform the crossover operation * @param probability Crossover probability * @param parent1 The first parent * @param parent2 The second parent * @return An array containing the two offsprings * @throws JMException */ public Solution[] doCrossover(double probability, Solution parent1, Solution parent2) throws JMException { Solution [] offSpring = new Solution[2]; offSpring[0] = new Solution(parent1); offSpring[1] = new Solution(parent2); try { if (PseudoRandom.randDouble() < probability) { for (int var = 0; var < parent1.getDecisionVariables().length; var++) { Binary p1 = (Binary)parent1.getDecisionVariables()[var]; Binary p2 = (Binary)parent2.getDecisionVariables()[var]; for (int bit = 0; bit < p1.getNumberOfBits(); bit++) { if (p1.bits_.get(bit) != p2.bits_.get(bit)) { if (PseudoRandom.randDouble() < 0.5) { ((Binary)offSpring[0].getDecisionVariables()[var]) .bits_.set(bit,p2.bits_.get(bit)); ((Binary)offSpring[1].getDecisionVariables()[var]) .bits_.set(bit,p1.bits_.get(bit)); } } } } //7. Decode the results for (int i = 0; i < offSpring[0].getDecisionVariables().length; i++) { ((Binary)offSpring[0].getDecisionVariables()[i]).decode(); ((Binary)offSpring[1].getDecisionVariables()[i]).decode(); } } }catch (ClassCastException e1) { Configuration.logger_.severe("HUXCrossover.doCrossover: Cannot perfom " + "SinglePointCrossover ") ; Class cls = java.lang.String.class; String name = cls.getName(); throw new JMException("Exception in " + name + ".doCrossover()") ; } return offSpring; } // doCrossover /** * Executes the operation * @param object An object containing an array of two solutions * @return An object containing the offSprings */ public Object execute(Object object) throws JMException { Solution [] parents = (Solution [])object; if (parents.length < 2) { Configuration.logger_.severe("HUXCrossover.execute: operator needs two " + "parents"); Class cls = java.lang.String.class; String name = cls.getName(); throw new JMException("Exception in " + name + ".execute()") ; } if (!(VALID_TYPES.contains(parents[0].getType().getClass()) && VALID_TYPES.contains(parents[1].getType().getClass())) ) { Configuration.logger_.severe("HUXCrossover.execute: the solutions " + "are not of the right type. The type should be 'Binary' of " + "'BinaryReal', but " + parents[0].getType() + " and " + parents[1].getType() + " are obtained"); Class cls = java.lang.String.class; String name = cls.getName(); throw new JMException("Exception in " + name + ".execute()") ; } // if Solution [] offSpring = doCrossover(probability_, parents[0], parents[1]); for (int i = 0; i < offSpring.length; i++) { offSpring[i].setCrowdingDistance(0.0); offSpring[i].setRank(0); } return offSpring; } // execute } // HUXCrossover