/* * 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.creditassigment; import hh.creditassignment.fitnessindicator.DoubleComparator; import hh.creditassignment.fitnessindicator.SortedLinkedList; import java.util.ArrayList; import org.moeaframework.core.Population; import org.moeaframework.core.Solution; /** * * @author SEAK2 */ public class AbstractRewardDefintion implements ICreditAssignment { protected CreditFunctionInputType inputType; protected CreditFitnessFunctionType fitType; protected CreditDefinedOn operatesOn; private Solution utopia; /** * stores all the objective values in sorted order to get bounds */ protected ArrayList<SortedLinkedList<Double>> sortedObjs; @Override public CreditFunctionInputType getInputType() { return inputType; } @Override public CreditFitnessFunctionType getFitnessType() { return fitType; } @Override public CreditDefinedOn getOperatesOn() { return operatesOn; } /** * Finds the utopia point in the population * * @param population the population to find the utopia point * @return the utopia point */ protected Solution computeUtopia(Population population) { utopia = new Solution(population.get(0).getNumberOfVariables(), population.get(0).getNumberOfObjectives()); for (int i = 0; i < population.get(0).getNumberOfObjectives(); i++) { double min = Double.MAX_VALUE; for (Solution soln : population) { min = Math.min(min, soln.getObjective(i)); } utopia.setObjective(i, min); } return utopia; } /** * Updates the utopia based on the new incoming solution. This method assumes that the utopia point never deteriorates * * @param offspring new solution entering the population * @return the updated utopia point */ protected Solution updateUtopia(Solution offspring) { for (int i = 0; i < offspring.getNumberOfObjectives(); i++) { utopia.setObjective(i, Math.min(utopia.getObjective(i), offspring.getObjective(i))); } return utopia; } /** * Normalizes the objectives to the solution based on the upper and lower * bounds of the objectives of the solutions in the population * * @param solution * @return */ protected double[] normalizeObjectives(Solution solution) { double[] normalizedObjs = new double[solution.getNumberOfObjectives()]; for (int i = 0; i < solution.getNumberOfObjectives(); i++) { double lowBound = sortedObjs.get(i).getFirst(); double upBound = sortedObjs.get(i).getLast(); normalizedObjs[i] = (solution.getObjective(i) - lowBound) / (upBound - lowBound); } return normalizedObjs; } //Computes the bounds on population protected void computeBounds(Population pop){ sortedObjs = new ArrayList<>(pop.get(0).getNumberOfObjectives()); for(int i = 0; i < pop.get(0).getNumberOfObjectives(); i++) { ArrayList<Double> objs = new ArrayList(pop.size()); for (Solution soln : pop) { objs.add(soln.getObjective(i)); } sortedObjs.add(new SortedLinkedList<>(objs, new DoubleComparator())); } } //updates the bounds based on a solution exiting the population protected void updateBoundsRemove(Solution removedSoln) { for (int i = 0; i < removedSoln.getNumberOfObjectives(); i++) { int index = sortedObjs.get(i).binaryFind(removedSoln.getObjective(i)); sortedObjs.get(i).remove(index); } } //updates the bounds based on a solution exiting the population protected void updateBoundsInsert(Solution newSolution) { for (int i = 0; i < newSolution.getNumberOfObjectives(); i++) { sortedObjs.get(i).add(newSolution.getObjective(i)); } } protected void updateBounds(Solution newSolution, Solution oldSolution){ updateBoundsRemove(oldSolution); updateBoundsInsert(newSolution); } @Override public void clear(){ sortedObjs.clear(); } }