package holeg.algorithm.objective_function; import holeg.model.Flexibility; import holeg.model.Holon; import holeg.model.HolonElement.Priority; import holeg.model.HolonObject; import holeg.model.HolonObject.HolonObjectState; import holeg.model.Model; import java.util.List; public class Evaluation { /** * Calculate the Fitness(Penelty) Value for a state (alias the calculated Position). * * @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 (Holon holon : model.holons) { float production = holon.getTotalProduction(); float consumption = holon.getTotalConsumption(); nw_fitness += Math.abs((production - consumption) / 100); //Energy is now everywhere positive } // calculate object_fitness for (Holon holon : model.holons) { object_fitness += holon.holonObjects.stream().filter(HolonObject::isConsumer).map( con -> holonObjectSupplyPenaltyFunction( con.getSupplyBarPercentage()) /*+ inactiveHolonElementPenalty(con.getModel())*/) .reduce(0.0, Double::sum); object_fitness += holon.holonObjects.stream().filter(HolonObject::isConsumer) .map(con -> StateToDouble(con.getState())).reduce(0.0, Double::sum); } List getAllFlexInUse = model.getAllFlexibilities().stream() .filter(flex -> flex.getState().equals(Flexibility.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.elementsStream().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; } } }