package holeg.algorithm.objective_function; import java.util.List; import holeg.model.Flexibility; import holeg.model.HolonObject; import holeg.model.HolonObject.HolonObjectState; import holeg.model.Flexibility.FlexState; import holeg.model.HolonElement.Priority; import holeg.ui.model.Model; //TODO(Tom2022-01-13) Fix Evaluation public class Evaluation { /** * Calculate the Fitness(Penelty) Value for a state (alias the calculated Position). * @param state * @return */ public static double getFitnessValueForState(Model model) { 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.cost / (double)flexWrapper.getDuration(); // }*/ // List getAllFlexInUse = state.getAllFlex().filter(flex -> flex.getState().equals(FlexState.IN_USE)).toList(); // for(Flexibility flex : getAllFlexInUse) { // flexFitness += Math.pow(sigma, (double)priorityToInt(flex.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 = (int)obj.getElements().count(); //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); } 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; } } }