package algorithm.objectiveFunction; import ui.model.DecoratedHolonObject; import ui.model.DecoratedNetwork; import ui.model.DecoratedState; import ui.model.DecoratedSwitch; import java.util.HashSet; import java.util.Locale; import algorithm.objectiveFunction.GraphMetrics.Graph; import api.TopologieAlgorithmFramework.IndexCable; public class TopologieObjectiveFunction { //Parameters //weight for f_g(H) static double w_eb = 0.3, w_max = 0.2, w_holon= 0.1, w_selection = .3, w_grid = 0.1; //--> f_eb parameter /** * Maximum Energie Difference(kappa) */ static double k_eb = 400000.f; /** * Maximum when all on Energie Difference(kappa) */ static double k_max = 450000.f; //--> f_holon parameter /** * maximum penalty from holon element distribution */ static double k_holon= 100000; //--> f_selection paramaeter; /** * average Maximum Cost for selction(kappa) of switch and elements. */ static double k_selection = 50000; static double cost_switch = 20; private static double cost_of_cable_per_meter = 0.8; //--> f_grid parameter /** * The avergae shortest path maximum length -> kappa for the squash function */ static double k_avg_shortest_path = 1600; //Disjpijoint path cant have zero as output it starts with the value 1 static double centerValue_disjoint_path = 1.0; static double k_disjoint_path = 2.4; static double lambda_avg_shortest_path = 10; static double lambda_disjoint_path = 10; static double k_grid = lambda_avg_shortest_path;// + lambda_disjoint_path; //pre-calculated parameters for partial function terms: /** * Pre calculated for the squash function *
* {@link TopologieObjectiveFunction#squash} */ static double squash_subtract = 1.0f / (1.f + (float) Math.exp(5.0)); static double range_for_k_avg_shortest_path = range(k_avg_shortest_path); static double range_for_k_disjoint_path = range(k_disjoint_path - centerValue_disjoint_path); 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_holon + w_selection + w_grid + w_max - 1) < 0.001)) { System.err.println("ParameterError in ObjectiveFunction: Sum of all weights 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 TopologieObjectiveFunction#squash} * * * @param state * @param moreInformation TODO * @return f_g value between 0 and 100 */ static public float getFitnessValueForState(DecoratedState state, int amountOfAddedSwitch, double addedCableMeters, boolean moreInformation) { //Calculate f_eb the penalty for unbalenced energy in the network double f_eb = 0; 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); } double f_maximum = 0; final int timestep = state.getTimestepOfState(); for(DecoratedNetwork net : state.getNetworkList()) { double maximumEnergy = 0; maximumEnergy += net.getConsumerList().stream().map(con -> con.getModel().getMaximumConsumptionPossible(timestep) - con.getModel().getMaximumProductionPossible(timestep)).reduce(0.f, Float::sum); maximumEnergy += net.getConsumerSelfSuppliedList().stream().map(con -> con.getModel().getMaximumConsumptionPossible(timestep) - con.getModel().getMaximumProductionPossible(timestep)).reduce(0.f, Float::sum); maximumEnergy += net.getSupplierList().stream().map(con -> con.getModel().getMaximumConsumptionPossible(timestep) - con.getModel().getMaximumProductionPossible(timestep)).reduce(0.f, Float::sum); f_maximum += Math.abs(maximumEnergy); } //calculate f_holon double f_holon = 0; for(DecoratedNetwork net : state.getNetworkList()) { double f_elements_deviation_production = net.getDeviationInProductionInNetworkForHolonObjects(); double f_elements_deviation_consumption = net.getDeviationInConsumptionInNetworkForHolonObjects(); double f_element = f_elements_deviation_production+f_elements_deviation_consumption; f_holon += f_element; } //calculating f_selection double f_selection = 0; double cost = 0; for(DecoratedNetwork net : state.getNetworkList()) { for(DecoratedHolonObject dHobject : net.getConsumerList()) { if(dHobject.getModel().getName().contains("Wildcard")){ if(dHobject.getModel().getName().length() > 9) { String costString = dHobject.getModel().getName().substring(9); cost += Double.parseDouble(costString); } } } for(DecoratedHolonObject dHobject : net.getConsumerSelfSuppliedList()) { if(dHobject.getModel().getName().contains("Wildcard")){ if(dHobject.getModel().getName().length() > 9) { String costString = dHobject.getModel().getName().substring(9); cost += Double.parseDouble(costString); } } } for(DecoratedHolonObject dHobject : net.getSupplierList()) { if(dHobject.getModel().getName().contains("Wildcard")){ if(dHobject.getModel().getName().length() > 9) { String costString = dHobject.getModel().getName().substring(9); cost += Double.parseDouble(costString); } } } } f_selection += cost; f_selection += cost_switch * amountOfAddedSwitch; f_selection += cost_of_cable_per_meter * addedCableMeters; if(moreInformation)System.out.println("CostForWildcards:" + cost + ", CostSwitches(#" + amountOfAddedSwitch +"):" + cost_switch * amountOfAddedSwitch + ", CostCables(" +addedCableMeters+ "m):" + cost_of_cable_per_meter * addedCableMeters); //calculating f_grid double f_grid = 0; //each network is a holon for(DecoratedNetwork net: state.getNetworkList()) { Graph G = GraphMetrics.convertDecoratedNetworkToGraph(net); //We have to penalize single Networks; if(G.V.length <= 1 || G.S.length <= 1) { f_grid += lambda_avg_shortest_path;// + lambda_disjoint_path; continue; } double avgShortestPath = GraphMetrics.averageShortestDistance(G); //double disjpointPaths = GraphMetrics.averageEdgeDisjointPathProblem(G); f_grid += avgShortestPathPenalty(avgShortestPath);// + disjoinPathPenalty(disjpointPaths); } //take average to encourage splitting f_grid /= state.getNetworkList().size(); //printUnsquashedValues(f_eb, f_maximum, f_holon, f_selection, f_grid); return (float) (w_eb * squash(f_eb, k_eb) + w_max * squash(f_maximum, k_max) + w_holon * squash(f_holon, k_holon) + w_selection * squash(f_selection, k_selection) + w_grid * squash(f_grid, k_grid)); } private static String doubleToString(double value) { return String.format (Locale.US, "%.2f", value); } private static double disjoinPathPenalty(double value) { return -(2.0 * lambda_disjoint_path) / (1 + Math.exp(- (value - centerValue_disjoint_path)/ range_for_k_disjoint_path)) + (2.0 * lambda_disjoint_path); } private static double avgShortestPathPenalty(double value) { return (2.0 * lambda_avg_shortest_path) / (1 + Math.exp(- value/ range_for_k_avg_shortest_path)) - lambda_avg_shortest_path; } /** * 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 ); } /** * 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; return (supplyPercentage < 100) ? -0.5 * supplyPercentage + 50: supplyPercentage - 100; } static void printDistribution(double f_eb, double f_maximum, double f_holon, double f_selection, double f_grid){ System.out.print(" f_eb(" + w_eb * squash(f_eb, k_eb) + ") "); System.out.print(" f_maximum(" + w_max * squash(f_maximum, k_max) + ") "); System.out.print(" f_holon(" + w_holon * squash(f_holon, k_holon) + ") "); System.out.print(" f_selection(" + w_selection * squash(f_selection, k_selection) + ") "); System.out.println(" f_grid(" + w_grid * f_grid + ") "); } static void printUnsquashedValues(double f_eb, double f_maximum, double f_holon, double f_selection, double f_grid){ System.out.print(" f_eb(" + f_eb + ") "); System.out.print(" f_maximum(" + f_maximum + ") "); System.out.print(" f_holon(" + f_holon + ") "); System.out.print(" f_selection(" + f_selection + ") "); System.out.println(" f_grid(" + f_grid + ") "); } }