package algorithm.objectiveFunction; import classes.HolonElement.Priority; import classes.HolonObject; import ui.model.DecoratedNetwork; import ui.model.DecoratedState; import ui.controller.FlexManager.FlexState; import ui.controller.FlexManager.FlexWrapper; import ui.model.DecoratedHolonObject.HolonObjectState; public class Evaluation { /** * Calculate the Fitness(Penelty) Value for a state (alias the calculated Position). * TODO: Make me better Rolf. * @param state * @return */ public static double getFitnessValueForState(DecoratedState state) { double fitness = 0.0; double nw_fitness =0.0; double object_fitness = 0.0; double flexFitness = 0.0; double sigma = 9; // calculate network_fitness for(DecoratedNetwork net : state.getNetworkList()) { float production = net.getSupplierList().stream().map(supplier -> supplier.getEnergyToSupplyNetwork()).reduce(0.0f, (a, b) -> a + b); float consumption = net.getConsumerList().stream().map(con -> con.getEnergyNeededFromNetwork()).reduce(0.0f, (a, b) -> a + b); nw_fitness += Math.abs((production - consumption)/100); //Energy is now everywhere positive } // calculate object_fitness for(DecoratedNetwork net : state.getNetworkList()) { object_fitness += net.getConsumerList().stream().map(con -> holonObjectSupplyPenaltyFunction(con.getSupplyBarPercentage()) /*+ inactiveHolonElementPenalty(con.getModel())*/).reduce(0.0, (a, b) -> (a + b)); object_fitness += net.getConsumerList().stream().map(con -> StateToDouble(con.getState())).reduce(0.0, (a,b) -> (a+b)); //object_fitness += net.getPassivNoEnergyList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b)); //object_fitness += net.getSupplierList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b)); //object_fitness += net.getConsumerSelfSuppliedList().stream().map(con -> inactiveHolonElementPenalty(con.getModel())).reduce(0.0, (a, b) -> (a + b)); } // calculate flexibility fitness old cost flex /*for(FlexWrapper flexWrapper :state.getFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)) { flexFitness += flexWrapper.getFlex().cost / (double)flexWrapper.getFlex().getDuration(); }*/ for(FlexWrapper flexWrapper :state.getFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)) { flexFitness += Math.pow(sigma, (double)priorityToInt(flexWrapper.getFlex().getElement().getPriority())) - 1; } fitness = nw_fitness + object_fitness + flexFitness; return fitness; } private static int priorityToInt(Priority priority) { switch(priority) { case Essential: return 3; case High: return 2; case Medium: return 1; case Low: default: return 0; } } /** * Untouched: * Function that returns the fitness depending on the number of elements deactivated in a single holon object * @param obj Holon Object that contains Holon Elements * @return fitness value for that object depending on the number of deactivated holon elements */ @SuppressWarnings("unused") private static double inactiveHolonElementPenalty(HolonObject obj) { float result = 0; int activeElements = obj.getNumberOfActiveElements(); int maxElements = obj.getElements().size(); //result = (float) Math.pow((maxElements -activeElements),2)*10; result = (float) Math.pow(5, 4* ( (float) maxElements - (float) activeElements)/ (float) maxElements) - 1; //System.out.console.println("max: " + maxElements + " active: " + activeElements + " results in penalty: " + result); return result; } /** * Untouched: * Calculates a penalty value based on the HOs current supply percentage * @param supplyPercentage * @return */ private static double holonObjectSupplyPenaltyFunction(float supplyPercentage) { double result = 0; /*if(supplyPercentage == 1) return result; else if(supplyPercentage < 1 && supplyPercentage >= 0.25) // undersupplied inbetween 25% and 100% result = (float) Math.pow(1/supplyPercentage, 2); else if (supplyPercentage < 0.25) //undersupplied with less than 25% result = (float) Math.pow(1/supplyPercentage,2); else if (supplyPercentage < 1.25) //Oversupplied less than 25% result = (float) Math.pow(supplyPercentage,3) ; else result = (float) Math.pow(supplyPercentage,4); //Oversupplied more than 25% if(Float.isInfinite(result) || Float.isNaN(result)) result = 1000; */ if(supplyPercentage <= 1.0) { result = Math.pow(5,(Math.abs((100 - (supplyPercentage*100)))/50 + 2)) - Math.pow(5, 2); } else { result = Math.pow(6,(Math.abs((100 - (supplyPercentage*100)))/50 + 2)) - Math.pow(6, 2); } if(result > 1000)System.out.println("supplyPenalty(" + supplyPercentage + ")=" + result); return result; } /** * If you want to get in touch with a reliable state? Working function not in use currently. * @param state * @return */ private static double StateToDouble(HolonObjectState state) { switch (state) { case NOT_SUPPLIED: return 150.0; case NO_ENERGY: return 150.0; case OVER_SUPPLIED: return 100.0; case PARTIALLY_SUPPLIED: return 100.0; case PRODUCER: return 0; case SUPPLIED: return 0; default: return 0; } } }