package algorithm.objectiveFunction; import ui.model.DecoratedNetwork; import ui.model.DecoratedState; import java.lang.Exception; import java.util.Locale; import classes.Flexibility; import classes.HolonElement.Priority; public class ObjectiveFunctionByCarlos { //Parameters //weight for f_g(H) static double w_eb = .3, w_state = .3, w_pro = .2, w_perf = .1, w_holon=.1; //kappas for squashing function static double k_eb = 1000000.f, k_state = 15000, k_pro = 2100, k_perf = 1100, k_holon= 200000; //theta for f_pro static double theta = 3; //kappas for f_perf: static double kappa_f_unre = 120; static double kappa_f_cool = 60*60*24; static double kappa_f_dur = 60*60; //lambdas for f_perf: static double lambda_f_unre = 10; static double lambda_f_cool = 10; static double lambda_f_dur = 10; static double lambda_f_change = 1000; //pre-calculated parameters for partial function terms: /** * Pre calculated for the squash function *
* {@link ObjectiveFunctionByCarlos#squash} */ static double squash_subtract = 1.0f / (1.f + (float) Math.exp(5.0)); static double range_for_kappa_f_unre = range(kappa_f_unre); static double range_for_kappa_f_cool = range(kappa_f_cool); static double range_for_kappa_f_dur = range(kappa_f_dur); static { //init checkParameter(); } /** * Check parameter Setting and print error when wrong values are put in. * Here should all invariants be placed to be checked on initialization. */ private static void checkParameter() { if(!(Math.abs(w_eb + w_state + w_pro + w_perf + w_holon - 1) < 0.001)) { System.err.println("ParameterError in ObjectiveFunction: w1 + w2 + w3 + w4 + w5 should be 1"); } } /** * ObjectifeFunction by Carlos. * Function computes f_g: * f_g = w1 * squash(f_eb, k1) + w2 * squash(f_state, k2) + w3 * squash(f_pro, k3) + w4 * squash(f_perf, k4) + w5 * squash(f_holon, k5) * * * squash is the squashing function {@link ObjectiveFunctionByCarlos#squash} * * * @param state * @return f_g value between 0 and 100 */ static public float getFitnessValueForState(DecoratedState state) { //Calculate f_eb the penalty for unbalenced energy in the network //TODO: Hier sollte zwischen den Netzwerken verschiedenen Holons unterschieden werden dies ist in den Formeln nicht wiedergegeben // Kann somit schlechte und gute Netzwerke ausgleichen // Implementierung ist wie im paper. double f_eb = 0; //sum over all objects for(DecoratedNetwork net : state.getNetworkList()) { double netEnergyDifference = 0; netEnergyDifference += net.getConsumerList().stream().map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets()).reduce(0.f, Float::sum); netEnergyDifference += net.getConsumerSelfSuppliedList().stream().map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets()).reduce(0.f, Float::sum); netEnergyDifference += net.getSupplierList().stream().map(sup -> sup.getEnergyProducing() - sup.getEnergySelfConsuming()).reduce(0.f, Float::sum); //abs f_eb += Math.abs(netEnergyDifference); } //Calculate f_state the penalty function for the supply state double f_state = 0; for(DecoratedNetwork net : state.getNetworkList()) { f_state += net.getConsumerList().stream().map(con -> supplyPenalty(con.getSupplyBarPercentage())).reduce(0., Double::sum); } //calculate f_pro the penalty function for priority usage // for each active flexibility punish double f_pro = 0; f_pro = state.getFlexManager().getAllFlexesOrderedThisTimeStep().stream().map(flex -> Math.pow(theta, priorityToDouble(flex.getElement().getPriority()) ) - 1.0).reduce(0.0, Double::sum); //calculate f_perf the penalty function for the quality of a flexibility used // and the subfuction f_unre, f_cool, f_dur double f_perf = 0; for(Flexibility flex : state.getFlexManager().getAllFlexesOrderedThisTimeStep()) { double f_unre = unresponsivnessPenalty(flex.getSpeed()); double f_cool = cooldownPenalty(flex.getCooldown()); double f_dur = durationPenalty(flex.getDuration()); f_perf += f_unre + f_cool + f_dur; } //calculate f_holon double f_holon = 0; for(DecoratedNetwork net : state.getNetworkList()) { double f_elements_diviation_production = net.getDiviationInProductionInNetworkForHolonObjects(); double f_elements_diviation_consumption = net.getDiviationInProductionInNetworkForHolonObjects(); double f_flexibility_diviation_consumption = net.getDiviationInFlexibilityConsumption(); double f_flexibility_diviation_production = net.getDiviationInFlexibilityProduction(); double con = net.getTotalConsumption(); double prod = net.getTotalProduction(); double flexcapProd = net.getFlexibilityProductionCapacity(); double flexcapCon = net.getFlexibilityConsumptionCapacity(); double f_change_positive = lambda_f_change - lambda_f_change * Math.min(1, (con > 0.0)? flexcapProd / con : 1.0 ); double f_change_negativ = lambda_f_change - lambda_f_change * Math.min(1, (prod > 0.0)? flexcapCon / prod: 1.0); double f_element = f_elements_diviation_production +f_elements_diviation_consumption; double f_flexibility = f_flexibility_diviation_consumption +f_flexibility_diviation_production; double f_change = f_change_positive + f_change_negativ; f_holon += f_element + f_flexibility + f_change; // System.out.print( "f_element=" + doubleToString(f_element)); // System.out.print( " f_flexibility=" + doubleToString(f_flexibility)); // System.out.println( " f_change=" + doubleToString(f_change)); // System.out.print( "f+elements=" + doubleToString(f_elements_diviation_production)); // System.out.print( " f-elements=" + doubleToString(f_elements_diviation_consumption)); // System.out.print( " f+flexibility" + doubleToString(f_flexibility_diviation_consumption)); // System.out.print( " f-flexibility" + doubleToString(f_flexibility_diviation_production)); // System.out.print( " f+change(" + doubleToString(flexcapProd) + "/" + doubleToString(con) + ")=" + doubleToString(f_change_positive)); // System.out.print( " f-change(" + doubleToString(flexcapCon) + "/" + doubleToString(prod) + ")="+ doubleToString(f_change_negativ)); // System.out.println( " sum=" + doubleToString(sum)); } // System.out.print( "f_ebVALUE=" + f_eb); // System.out.print( " f_state=" + f_state); // System.out.print( " f_pro=" + f_pro); // System.out.print( " f_perf=" + f_perf); // System.out.println( " f_holon=" + f_holon); double q1 = squash(f_eb, k_eb); double q2 = squash(f_state, k_state); double q3 = squash(f_pro, k_pro); double q4 = squash(f_perf, k_perf); double q5 = squash(f_holon, k_holon); // System.out.print( "f_eb=" + q1); // System.out.print( " f_state=" + q2); // System.out.print( " f_pro=" + q3); // System.out.print( " f_perf=" + q4); // System.out.println( " f_holon=" + q5); // return (float) (w_eb * q1 + w_state * q2 + w_pro * q3 + w_perf * q4 + w_holon * q5); //return (float) (f_eb + f_state + f_pro + f_perf + f_holon); } private static String doubleToString(double value) { return String.format (Locale.US, "%.2f", value); } /** * The squashing function in paper * @param x the input * @param kappa the corresponding kappa * @return */ static public double squash(double x, double kappa) { return 100.f/(1.0f + Math.exp(-(10.f * (x - kappa/2.f))/ kappa)) - squash_subtract; } /** * f_sup in paper * @param supply from 0 to 1 * @return */ static public double supplyPenalty(double supply) { double supplyPercentage = 100 * supply; // double test = (supplyPercentage < 100) ? -0.5 * supplyPercentage + 50: supplyPercentage - 100; return (supplyPercentage < 100) ? -0.5 * supplyPercentage + 50: supplyPercentage - 100; } /** * prio function in the paper * @param priority * @return */ private static double priorityToDouble(Priority priority) { switch(priority) { case Essential: return 3.; case High: return 2.; case Medium: return 1.; case Low: default: return 0.; } } /** * Attention Math.log calcultae ln not log * @param kappa * @return */ private static double range(double kappa) { return kappa / Math.log(Math.pow(2.0, 0.05) - 1.0 ); } /** * f_unre * @param unresponsiv * @return */ private static double unresponsivnessPenalty(double unresponsiv) { return (2.0 * lambda_f_unre) / Math.exp(- unresponsiv/ range_for_kappa_f_unre) - lambda_f_unre; } /** * f_cool * @param cooldown * @return */ private static double cooldownPenalty(double cooldown) { return (2.0 * lambda_f_cool) / Math.exp(- cooldown/ range_for_kappa_f_cool) - lambda_f_cool; } private static double durationPenalty(double duration) { double lambda_dur_times2 = 2.0 * lambda_f_dur; return - lambda_dur_times2 / Math.exp(- duration/ range_for_kappa_f_dur) + lambda_dur_times2; } }