/* * 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.nextheuristic; import hh.creditassigment.Credit; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import org.moeaframework.core.ParallelPRNG; import org.moeaframework.core.Variation; /** * This abstract implements the interface INextHeuristic. Classes that * extend this abstract class are required to have some credit repository * @author nozomihitomi */ public abstract class AbstractOperatorSelector implements INextHeuristic{ /** * Random number generator for selecting heuristics. */ protected final ParallelPRNG pprng = new ParallelPRNG(); /** * The number of times nextHeuristic() is called */ private int iterations; /** * Hashmap to store the qualities of the heuristics */ protected HashMap<Variation,Double> qualities; /** * The heuristics from which the selector can choose from */ protected Collection<Variation> operators; /** * Constructor requires a credit repository that stores credits earned by * heuristics. * @param operators the collection of operators used to conduct search */ public AbstractOperatorSelector(Collection<Variation> operators){ this.iterations = 0; this.qualities = new HashMap<>(); this.operators = operators; resetQualities(); } /** * Method finds the heuristic that maximizes the function to be maximized. * The function to be maximized may be related to credits or a function of * credits. If there are two or more heuristics that maximize the function * (i.e. there is a tie) a random heuristic will be selected from the tied * maximizing heuristics * @param operators the set of heuristics to maximize over * @return the heuristic that maximizes the function2maximize */ protected Variation argMax(Collection<Variation> operators){ Iterator<Variation> iter = operators.iterator(); ArrayList<Variation> ties = new ArrayList(); Variation leadOperator = null; double maxVal = Double.NEGATIVE_INFINITY; try{ while(iter.hasNext()){ Variation operator_i = iter.next(); if(leadOperator==null){ leadOperator = operator_i; maxVal = function2maximize(operator_i); continue; } if(function2maximize(operator_i)>maxVal){ maxVal = function2maximize(operator_i); leadOperator = operator_i; ties.clear(); }else if(function2maximize(operator_i)==maxVal){ ties.add(operator_i); } } //if there are any ties in the credit score, select randomly (uniform //probability)from the heuristics that tied at lead if(!ties.isEmpty()){ leadOperator = getRandomOperator(ties); } }catch(NoSuchMethodException ex){ Logger.getLogger(AbstractOperatorSelector.class.getName()).log(Level.SEVERE, null, ex); } return leadOperator; } /** * The function to be maximized by argMax(). The function to be maximized * may be related to credits or a function of credits. If an * IHeuristicSeletor uses this method, it should be overridden * @param operator input to the function * @return the value of the function with the given input * @throws java.lang.NoSuchMethodException If this method is used without * being overridden, then it throws a NoSuchMethodException */ protected double function2maximize(Variation operator) throws NoSuchMethodException{ throw new NoSuchMethodException("Need to override this method"); } /** * Selects a random heuristic from a collection of heuristics with uniform * probability * @param operators the collection to draw a random heuristic from * @return the randomly selected heuristic */ protected Variation getRandomOperator(Collection<Variation> operators){ return pprng.nextItem(new ArrayList<>(operators)); } /** * Increments the number of times nextHeuristic() has been called by one */ protected void incrementIterations(){ iterations++; } /** * Returns the number of times nextHeuristic() has been called * @return the number of times nextHeuristic() has been called */ @Override public int getNumberOfIterations(){ return iterations; } /** * Resets stored qualities and iteration count */ @Override public void reset(){ resetQualities(); iterations = 0; } /** * Clears qualities and resets them to 0. */ public final void resetQualities(){ Iterator<Variation> iter = operators.iterator(); while(iter.hasNext()){ //all heuristics have 0 quality at the beginning qualities.put(iter.next(), 0.0); } } @Override public HashMap<Variation, Double> getQualities() { return qualities; } /** * Gets the heuristics available to the hyper-heuristic. * @return */ @Override public Collection<Variation> getOperators(){ return operators; } /** * Checks the quality of the heuristic. If the quality becomes negative, it is reset * to 0.0. Only updates those heuristics that were just rewarded. */ protected void checkQuality(){ for(Variation heuristic:qualities.keySet()) { //if current quality becomes negative, adjust to 0 double qual = qualities.get(heuristic); if (qual < 0.0 || Double.isNaN(qual)) { qualities.put(heuristic, 0.0); } } } }