///* // * 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.history.CreditHistory; //import hh.nextheuristic.INextHeuristic; //import hh.history.OperatorQualityHistory; //import hh.creditassigment.CreditFunctionInputType; //import hh.creditassigment.ICreditAssignment; //import hh.creditassigment.Credit; //import hh.creditassignment.offspringparent.AbstractOffspringParent; //import hh.creditassignment.offspringpopulation.AbstractOffspringPopulation; //import hh.creditassignment.populationcontribution.AbstractPopulationContribution; //import hh.history.OperatorSelectionHistory; //import java.util.ArrayList; //import java.util.Collection; //import java.util.HashMap; //import java.util.Iterator; //import org.apache.commons.lang3.ArrayUtils; //import org.moeaframework.algorithm.EpsilonMOEA; //import org.moeaframework.core.EpsilonBoxDominanceArchive; //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.operator.real.PM; // ///** // * // * @author Nozomi // */ //public class HeMOEA extends EpsilonMOEA 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; // // /** // * This counter keeps track of the archive's epsilon progress // */ // private int epsilonProgressCounter; // // /** // * This stores the value of the epsilon progress from the last iteration // */ // private int prevEpsilonProgressCount; // // /** // * The allowed number of iterations without epsilon progress // */ // private final int lagWindow; // // /** // * The injection rate. The fraction of the population to populate with // * archival solutions // */ // private final double injectionRate; // // /** // * Polynomial mutation operator used when after injecting archival solutions // * into population does not fill up population // */ // private PM pm; // // /** // * 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; // // /** // * Iteration count // */ // private int iteration; // // /** // * Name to id the hyper-heuristic // */ // private String name; // // /** // * Pareto Front // */ // private NondominatedPopulation paretoFront; // // /** // * The population contribution rewards from the previous iteration // */ // private HashMap<Variation, Credit> prevPopContRewards; // // /** // * Creates an instance of a hyper heuristic e-MOEA // * // * @param problem the problem to solve // * @param population the type of population // * @param archive the type of archive to implement // * @param selection type of selection used to select higher fitness // * individuals // * @param initialization the method to initialize the population // * @param heuristicSelector the heuristic selector to use in the // * hyper-heuristic // * @param creditDef the credit definition to score the performance of the // * low-level heuristics // * @param injectionRate The fraction of the population to populate with // * archival solutions // * @param lagWindow The allowed number of iterations without epsilon // * progress // */ // public HeMOEA(Problem problem, Population population, // EpsilonBoxDominanceArchive archive, Selection selection, // Initialization initialization, INextHeuristic heuristicSelector, // ICreditAssignment creditDef, double injectionRate, int lagWindow) { // super(problem, population, archive, selection, null, initialization); // // 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(); // this.iteration = 0; // this.epsilonProgressCounter = 0; // this.injectionRate = injectionRate; // this.pm = new PM(1 / problem.getNumberOfVariables(), 20); // this.lagWindow = lagWindow; // // //Initialize the stored pareto front // super.initialize(); // this.paretoFront = new NondominatedPopulation(getPopulation()); // // //initialize the previous population contribution rewards to all zero for each heuristic // prevPopContRewards = new HashMap<>(); // for (Variation heur : heuristics) { // prevPopContRewards.put(heur, new Credit(0, 0.0)); // } // } // // @Override // public String getName() { // return name; // } // // @Override // public void setName(String name) { // this.name = name; // } // // /** // * An iterations of this algorithm will select the next heuristic to be // * applied, select the parents for that heuristic and select one child to // * get evaluated. For heuristics that create more than one offspring, a // * random offspring will be selected with uniform probability // */ // @Override // public void iterate() { // iteration++; //// System.out.println(paretoFront.size() + " iteration " + iteration); // //Check epsilon progress (if the epsilon domination count increases in archive) //// if (prevEpsilonProgressCount == getArchive().getNumberOfDominatingImprovements()) { //// epsilonProgressCounter++; //// if (epsilonProgressCounter > lagWindow) { //// injectFromArchive(); //// } //// } // // //select next heuristic // Variation operator = operatorSelector.nextHeuristic(); // operatorSelectionHistory.add(operator,this.numberOfEvaluations); // // Solution[] parents; // // Solution refParent; //used in OffspringParent Rewads // if (archive.size() <= 1) { // parents = selection.select(operator.getArity(), population); // refParent = parents[pprng.nextInt(parents.length)]; // } else { // refParent = archive.get(pprng.nextInt(archive.size())); // parents = ArrayUtils.add( // selection.select(operator.getArity() - 1, population), refParent); // } // // Solution[] children = operator.evolve(parents); // if (creditDef.getInputType() == CreditFunctionInputType.OP) { // double creditValue = 0; // for (Solution child : children) { // evaluate(child); // Solution removedSoln = addToPopulation(child); // if (removedSoln != null) { // //credit definitions operating on population and archive does // //NOT modify the population by adding the child to the population/archive // switch (creditDef.getOperatesOn()) { // case PARENT: // creditValue += ((AbstractOffspringParent) creditDef).compute(child, refParent, population, removedSoln); // break; // default: // throw new NullPointerException("Credit definition not " // + "recognized. Used " + creditDef.getInputType() + "."); // } // } // archive.add(child); // } // 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) { // evaluate(child); // Solution removedSoln = addToPopulation(child); // if (removedSoln != null) { //solution made it in population // //credit definitions operating on PF and archive will // //modify the nondominated population by adding the child to the nondominated population. // switch (creditDef.getOperatesOn()) { // case PARETOFRONT: // creditValue += ((AbstractOffspringPopulation) creditDef).compute(child, paretoFront); // archive.add(child); // break; // case ARCHIVE: // creditValue += ((AbstractOffspringPopulation) creditDef).compute(child, archive); // 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) { // ArrayList<Solution> removedFromArchive = new ArrayList(); // ArrayList<Solution> childrenInArchive = new ArrayList(); // for (Solution child : children) { // evaluate(child); // child.setAttribute("iteration", new SerializableVal(iteration)); // child.setAttribute("heuristic", new SerializableVal(operator.toString())); // Collection<Solution> removedA = archive.addAndReturnRemovedSolutions(child); // if (archive.isChanged()) { // childrenInArchive.add(child); // if (removedA != null) { // removedFromArchive.addAll(removedA); // } // } // } // HashMap<Variation, Credit> popContRewards; // switch (creditDef.getOperatesOn()) { // case PARETOFRONT: // ArrayList<Solution> removedFromPF = new ArrayList(); // ArrayList<Solution> childrenInPF = new ArrayList(); // for (Solution child : children) { // Collection<Solution> removedPF = paretoFront.addAndReturnRemovedSolutions(child); // if (paretoFront.isChanged()) { // childrenInPF.add(child); // if (removedPF != null) { // removedFromPF.addAll(removedPF); // } // } // } // //updated only if reward def uses the PF // if (!paretoFront.isChanged()) { // popContRewards = reusePrevPopContRewards(); // } else { // popContRewards = ((AbstractPopulationContribution) creditDef). // compute(paretoFront, heuristics, this.numberOfEvaluations); // prevPopContRewards = popContRewards; //update prevPopContRewards for future iterations // } // break; // case ARCHIVE: // if (!archive.isChanged()) { // popContRewards = reusePrevPopContRewards(); // } else { // popContRewards = ((AbstractPopulationContribution) creditDef). // compute(archive, heuristics, this.numberOfEvaluations); // prevPopContRewards = popContRewards; //update prevPopContRewards for future iterations // } // 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(); // } // // /** // * This method is used when there is a stagnation in the epsilon progress. // * It clears out the population and injects a portion of the archive into // * the population. If there are more spaces remaining in the population // * after that, the injected solutions are mutated until the desired // * population size is reached // */ // private void injectFromArchive() { // int size = population.size(); // population.clear(); // for (int i = 0; i < Math.floor(((double) size) * injectionRate); i++) { // ((NondominatedPopulation) population).forceAddWithoutCheck(archive.get(pprng.nextInt(archive.size()))); // } // while (population.size() < size) { // Solution[] solution2Mutate = new Solution[]{population.get(pprng.nextInt(population.size()))}; // Solution[] mutated = pm.evolve(solution2Mutate); // ((NondominatedPopulation) population).forceAddWithoutCheck(mutated[0]); // } // } // // /** // * reuses the previous population contribution rewards. This method updates // * the iteration coutner in the rewards from the previous iteration // * // * @return the rewards for each heuristic with the up to date iteration // * count // */ // private HashMap<Variation, Credit> reusePrevPopContRewards() { // for (Variation heur : heuristics) { // Credit r = new Credit(iteration, prevPopContRewards.get(heur).getValue()); // prevPopContRewards.put(heur, r); // } // return prevPopContRewards; // } // // /** // * Updates the quality history every iteration for each heuristic according // * to the INextHeuristic class used // */ // private void updateQualityHistory() { // HashMap<Variation, Double> currentQualities = operatorSelector.getQualities(); // for (Variation heuristic : heuristics) { // qualityHistory.add(heuristic, currentQualities.get(heuristic)); //// System.out.print(currentQualities.get(heuristic) + "\t"); // } //// System.out.println(); // } // // /** // * 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() { // iteration = 0; // 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; // } // //}