|
@@ -4,46 +4,50 @@ import ui.model.DecoratedNetwork;
|
|
|
import ui.model.DecoratedState;
|
|
|
import java.lang.Exception;
|
|
|
|
|
|
+import classes.Flexibility;
|
|
|
+import classes.HolonElement.Priority;
|
|
|
+
|
|
|
public class ObjectiveFunctionByCarlos {
|
|
|
- //Parameter
|
|
|
- static float lambda;
|
|
|
+ //Parameters
|
|
|
+
|
|
|
//weight for f_g(H)
|
|
|
- static float w1 = .2f, w2 = .2f, w3 = .2f, w4 = .2f, w5=.2f;
|
|
|
+ static double w_eb = .35f, w_state = .35f, w_pro = .1f, w_perf = .1f, w5=.1f;
|
|
|
+
|
|
|
//kappas for squashing function
|
|
|
- static float k1 = .2f, k2 = .2f, k3 = .2f, k4 = .2f, k5=.2f;
|
|
|
+ static double k_eb = 1000000.f, k_state = 30000, 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;
|
|
|
|
|
|
|
|
|
- //pre-calculated parameters:
|
|
|
+
|
|
|
+
|
|
|
+ //pre-calculated parameters for partial function terms:
|
|
|
/**
|
|
|
* Pre calculated for the squash function
|
|
|
* <br>
|
|
|
* {@link ObjectiveFunctionByCarlos#squash}
|
|
|
*/
|
|
|
- static float squash_subtract = 1.0f / (1.f + (float) Math.exp(5.0));
|
|
|
-
|
|
|
+ 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 {
|
|
|
- //pre-calculations
|
|
|
- System.out.println("Precalculations");
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- double doubleBaseTest = Math.exp(300);
|
|
|
- double doubleMax = Double.MAX_VALUE;
|
|
|
- float floatBaseTest = (float)Math.exp(300);
|
|
|
- float floatMax = Float.MAX_VALUE;
|
|
|
-
|
|
|
-
|
|
|
- System.out.println("floatMax" + floatMax);
|
|
|
- System.out.println("floatBaseTest" + floatBaseTest);
|
|
|
- System.out.println("doubleMax" + doubleMax);
|
|
|
- System.out.println("doubleBaseTest" + doubleBaseTest);
|
|
|
-
|
|
|
-
|
|
|
+ //init
|
|
|
checkParameter();
|
|
|
+ double k = 9.14E72;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -51,7 +55,7 @@ public class ObjectiveFunctionByCarlos {
|
|
|
* Here should all invariants be placed to be checked on initialization.
|
|
|
*/
|
|
|
private static void checkParameter() {
|
|
|
- if(!(Math.abs(w1 + w2 + w3 + w4 + w5 - 1) < 0.001)) {
|
|
|
+ if(!(Math.abs(w_eb + w_state + w_pro + w_perf + w5 - 1) < 0.001)) {
|
|
|
System.err.println("ParameterError in ObjectiveFunction: w1 + w2 + w3 + w4 + w5 should be 1");
|
|
|
}
|
|
|
}
|
|
@@ -66,7 +70,7 @@ public class ObjectiveFunctionByCarlos {
|
|
|
*
|
|
|
*
|
|
|
* @param state
|
|
|
- * @return f_g
|
|
|
+ * @return f_g value between 0 and 100
|
|
|
*/
|
|
|
static public float getFitnessValueForState(DecoratedState state) {
|
|
|
|
|
@@ -75,7 +79,7 @@ public class ObjectiveFunctionByCarlos {
|
|
|
//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.
|
|
|
- float f_eb = 0;
|
|
|
+ double f_eb = 0;
|
|
|
//sum over all objects
|
|
|
for(DecoratedNetwork net : state.getNetworkList()) {
|
|
|
f_eb += net.getConsumerList().stream().map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets()).reduce(0.f, Float::sum);
|
|
@@ -83,65 +87,131 @@ public class ObjectiveFunctionByCarlos {
|
|
|
f_eb += net.getSupplierList().stream().map(sup -> sup.getEnergyProducing() - sup.getEnergySelfConsuming()).reduce(0.f, Float::sum);
|
|
|
}
|
|
|
//abs
|
|
|
- f_eb = (float) Math.abs(f_eb);
|
|
|
+ f_eb = Math.abs(f_eb);
|
|
|
|
|
|
//Calculate f_state the penalty function for the supply state
|
|
|
- float f_state = 0;
|
|
|
+ double f_state = 0;
|
|
|
for(DecoratedNetwork net : state.getNetworkList()) {
|
|
|
- f_state += net.getConsumerList().stream().map(con -> supplyPenalty(con.getSupplyBarPercentage())).reduce(0.f, Float::sum);
|
|
|
+ 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()) )).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 f_change_positive = (con > 0.0)? net.getFlexibilityProductionCapacity() / con : 0.0;
|
|
|
+ double f_change_negativ = (prod > 0.0)? net.getFlexibilityConsumptionCapacity() / prod: 0.0;
|
|
|
+
|
|
|
+ f_holon += f_elements_diviation_production + f_elements_diviation_consumption
|
|
|
+ + f_flexibility_diviation_consumption + f_flexibility_diviation_production + f_change_positive +f_change_negativ;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+// System.out.print( "f_eb=" + 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);
|
|
|
|
|
|
|
|
|
- return 0.0f + lambda;
|
|
|
+ return (float) (w_eb * squash(f_eb, k_eb) + w_state * squash(f_state, k_state) + w_pro * squash(f_pro, k_pro) + w_perf * squash(f_perf, k_perf) + w5 * squash(f_holon, k_holon));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- *
|
|
|
+ * The squashing function in paper
|
|
|
* @param x the input
|
|
|
* @param kappa the corresponding kappa
|
|
|
* @return
|
|
|
*/
|
|
|
- static public float squash(float x, float kappa) {
|
|
|
- return 100.f/(1.0f + (float)Math.exp(-(10.f * (x - kappa/2.f))/ kappa)) - squash_subtract;
|
|
|
+ static public double squash(double x, double kappa) {
|
|
|
+ return 100.f/(1.0f + Math.exp(-(10.f * (x - kappa/2.f))/ kappa)) - squash_subtract;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- *
|
|
|
- * @param supplyPercentage from 0 to 1
|
|
|
+ * f_sup in paper
|
|
|
+ * @param supply from 0 to 1
|
|
|
* @return
|
|
|
*/
|
|
|
- static public float supplyPenalty(float supplyPercentage) {
|
|
|
- float f_base = base(supplyPercentage);
|
|
|
- return (float)(Math.pow(f_base, 100 - 100 * supplyPercentage) - Math.pow(f_base, 2));
|
|
|
+ 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;
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
- * TODO: f_base wird im Paper mit e angegeben. f_eb mit exp() warum nicht einheitlich?
|
|
|
- *
|
|
|
- * @param supplyPercentage from 0 to 1
|
|
|
- * @return 5 or 6 but with fancy math
|
|
|
+ * prio function in the paper
|
|
|
+ * @param priority
|
|
|
+ * @return
|
|
|
*/
|
|
|
- static public float base(float supplyPercentage) {
|
|
|
- //TODO: Fancy kann aber leicht zu overflow fürhen denn e1000 ist zu groß für double max double 1.7976931348623157E308 und max float 3.4028235E38
|
|
|
- //Oder BigDecimal aber müsste echt nicht sein.
|
|
|
- double euler = Math.exp(1000.0 - 1000.0 * supplyPercentage);
|
|
|
- return (float) ((5 * euler + 6 ) / (euler + 1));
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- //Suggestion
|
|
|
- // return (supplyPercentage < 1.0f)? 5.0: 6.0; einfach und gut
|
|
|
-
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
}
|