/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package hh.hyperheuristics; import hh.creditassigment.Credit; import hh.creditassigment.CreditFunctionInputType; import hh.creditassigment.ICreditAssignment; import hh.creditassignment.offspringparent.AbstractOffspringParent; import hh.creditassignment.offspringpopulation.AbstractOffspringPopulation; import hh.creditassignment.populationcontribution.AbstractPopulationContribution; import hh.history.CreditHistory; import hh.history.OperatorQualityHistory; import hh.history.OperatorSelectionHistory; import hh.nextheuristic.INextHeuristic; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import hh.moea.SteadyStateIBEA; import org.moeaframework.algorithm.IBEA; import org.moeaframework.core.FitnessEvaluator; import org.moeaframework.core.Indicator; import org.moeaframework.core.Initialization; import org.moeaframework.core.NondominatedPopulation; import org.moeaframework.core.ParallelPRNG; import org.moeaframework.core.Population; import org.moeaframework.core.Problem; import org.moeaframework.core.Selection; import org.moeaframework.core.Solution; import org.moeaframework.core.Variation; import org.moeaframework.core.fitness.IndicatorFitnessEvaluator; /** * This hyperheuristic is uses R2 MOEA to manage the population. R2 MOEA is * steady state indicator based algorithm developed by Diaz et al in "A ranking * method based on the R2 indicator for many-objective optimization" 2013 IEEE * Congress on Evolutionary Computation * * @author SEAK2 */ public class AOSIBEA extends IBEA implements IHyperHeuristic { /** * The type of heuristic selection method */ private final INextHeuristic operatorSelector; /** * The Credit definition to be used that defines how much credit to receive * for certain types of solutions */ private final ICreditAssignment creditDef; /** * The history that stores all the heuristics selected by the hyper * heuristics. History can be extracted by getSelectionHistory(). Used for * analyzing the results to see the dynamics of heuristics selected */ private OperatorSelectionHistory operatorSelectionHistory; /** * The history that stores all the rewards received by the operators. Used * for analyzing the results to see the dynamics in rewards */ private CreditHistory creditHistory; /** * The set of heuristics that the hyper heuristic is able to work with */ private final Collection<Variation> heuristics; /** * The selection operator. */ private final Selection selection; /** * The history of the heuristics' qualities over time. Used for analyzing * the results to see the dynamics of the heuristic qualities */ private OperatorQualityHistory qualityHistory; /** * parallel purpose random generator */ private final ParallelPRNG pprng; private double[] upperbound; private double[] lowerbound; private NondominatedPopulation paretofront; /** * Name to id the hyper-heuristic */ private String name; public AOSIBEA(Problem problem, Population population, NondominatedPopulation archive, Selection selection, Initialization initialization, IndicatorFitnessEvaluator fitnessEvaluator, INextHeuristic heuristicSelector, ICreditAssignment creditDef) { super(problem, archive, initialization, null, fitnessEvaluator); this.heuristics = heuristicSelector.getOperators(); this.selection = selection; this.operatorSelector = heuristicSelector; this.creditDef = creditDef; this.operatorSelectionHistory = new OperatorSelectionHistory(heuristics); this.qualityHistory = new OperatorQualityHistory(heuristics); this.creditHistory = new CreditHistory(heuristics); this.pprng = new ParallelPRNG(); //Initialize super.initialize(); paretofront = new NondominatedPopulation(getPopulation()); } @Override protected void iterate() { Population offspring = new Population(); int populationSize = population.size(); Population prevGen = new Population(population); lowerbound = fitnessEvaluator.getLowerbound(); upperbound = fitnessEvaluator.getUpperbound(); while (offspring.size() < populationSize) { //select next heuristic Variation operator = operatorSelector.nextHeuristic(); operatorSelectionHistory.add(operator, this.numberOfEvaluations); Solution[] parents = selection.select(operator.getArity(), population); Solution[] children = operator.evolve(parents); offspring.addAll(children); evaluateAll(children); if (creditDef.getInputType() == CreditFunctionInputType.OP) { double creditValue = 0.0; for (Solution child : children) { Solution refParent = parents[pprng.nextInt(parents.length)]; switch (creditDef.getOperatesOn()) { case PARENT: creditValue += ((AbstractOffspringParent) creditDef).compute(fitnessEvaluator.normalize(child), fitnessEvaluator.normalize(refParent), null, null); break; default: throw new NullPointerException("Credit definition not " + "recognized. Used " + creditDef.getInputType() + "."); } } Credit reward = new Credit(this.numberOfEvaluations, creditValue); operatorSelector.update(reward, operator); creditHistory.add(operator, reward); } else if (creditDef.getInputType() == CreditFunctionInputType.SI) { double creditValue = 0.0; for (Solution child : children) { switch (creditDef.getOperatesOn()) { case POPULATION: prevGen.add(child); creditValue += ((AbstractOffspringPopulation) creditDef).compute(child, prevGen); break; default: throw new NullPointerException("Credit definition not " + "recognized. Used " + creditDef.getInputType() + "."); } } Credit reward = new Credit(this.numberOfEvaluations, creditValue); operatorSelector.update(reward, operator); creditHistory.add(operator, reward); } else if (creditDef.getInputType() == CreditFunctionInputType.CS) { for (Solution child : children) { prevGen.add(child); child.setAttribute("heuristic", new SerializableVal(operator.toString())); } HashMap<Variation, Credit> popContRewards; switch (creditDef.getOperatesOn()) { case POPULATION: popContRewards = ((AbstractPopulationContribution) creditDef). compute(prevGen, heuristics, this.numberOfEvaluations); break; default: throw new NullPointerException("Credit definition not " + "recognized. Used " + creditDef.getInputType() + "."); } Iterator<Variation> iter = popContRewards.keySet().iterator(); while (iter.hasNext()) { Variation operator_i = iter.next(); operatorSelector.update(popContRewards.get(operator_i), operator_i); creditHistory.add(operator_i, new Credit(this.numberOfEvaluations, popContRewards.get(operator_i).getValue())); } } else { throw new UnsupportedOperationException("RewardDefinitionType not recognized "); } // updateQualityHistory(); } population.addAll(offspring); fitnessEvaluator.evaluate(population); while (population.size() > populationSize) { int worstIndex = findWorstIndex(); fitnessEvaluator.removeAndUpdate(population, worstIndex); } } private Population copyPrevGen(Population pop) { Population copyPop = new Population(); for (Solution solution : pop) { Solution copySolution = solution.copy(); copySolution.setAttribute("prevfitness", (double) solution.getAttribute(FitnessEvaluator.FITNESS_ATTRIBUTE)); copyPop.add(copySolution); } return copyPop; } private void updatedBound(Solution solution) { for (int i = 0; i < lowerbound.length; i++) { lowerbound[i] = Math.min(lowerbound[i], solution.getObjective(i)); upperbound[i] = Math.max(upperbound[i], solution.getObjective(i)); } } public Solution normalize(Solution solution) { Solution out = solution.copy(); for (int i = 0; i < solution.getNumberOfObjectives(); i++) { out.setObjective(i, (solution.getObjective(i) - lowerbound[i]) / (upperbound[i] - lowerbound[i])); } return out; } /** * Returns the ordered history of operators that were selected * * @return The ordered history of operators that were selected */ @Override public OperatorSelectionHistory getSelectionHistory() { return operatorSelectionHistory; } /** * gets the quality history stored for each operator in the hyper-heuristic * * @return */ @Override public OperatorQualityHistory getQualityHistory() { return qualityHistory; } /** * gets the credit history stored for each operator in the hyper-heuristic * * @return */ @Override public CreditHistory getCreditHistory() { return creditHistory; } /** * Reset the hyperheuristic. Clear all selection history and the credit * repository. Clears the population and the archive */ @Override public void reset() { operatorSelectionHistory.reset(); operatorSelector.reset(); numberOfEvaluations = 0; qualityHistory.clear(); population.clear(); archive.clear(); creditDef.clear(); } @Override public ICreditAssignment getCreditDefinition() { return creditDef; } @Override public INextHeuristic getNextHeuristicSupplier() { return operatorSelector; } @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } }