ObjectiveFunctionByCarlos.java 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package holeg.algorithm.objective_function;
  2. import java.util.List;
  3. import java.util.logging.Logger;
  4. import holeg.model.Flexibility;
  5. import holeg.model.Flexibility.FlexState;
  6. import holeg.model.HolonElement.Priority;
  7. import holeg.ui.model.DecoratedNetwork;
  8. import holeg.ui.model.DecoratedState;
  9. public class ObjectiveFunctionByCarlos {
  10. // Parameters
  11. private static final Logger LOGGER = Logger.getLogger(ObjectiveFunctionByCarlos.class.getName());
  12. // weight for f_g(H)
  13. static double w_eb = .3, w_state = .3, w_pro = .2, w_perf = .1, w_holon = .1;
  14. // killswitch weights
  15. // static double w_eb = 0.5, w_state = 0.5, w_pro = 0.0f, w_perf = .0,
  16. // w_holon=.0;
  17. // kappas for squashing function
  18. //
  19. // static double k_eb = 1050000.f, k_state = 10000, k_pro = 2000, k_perf =
  20. // 11000, k_holon= 150000;
  21. // oversupplied
  22. static double k_eb = 750000.f, k_state = 20000, k_pro = 3000, k_perf = 15000, k_holon = 200000;
  23. // old values undersupplied
  24. // static double k_eb = 1000000.f, k_state = 15000, k_pro = 2100, k_perf = 12000, k_holon= 200000;
  25. // theta for f_pro
  26. static double theta = 3;
  27. // kappas for f_perf:
  28. static double kappa_f_unre = 120;
  29. static double kappa_f_cool = 60 * 60 * 24;
  30. static double kappa_f_dur = 60 * 60;
  31. // lambdas for f_perf:
  32. static double lambda_f_unre = 10;
  33. static double lambda_f_cool = 10;
  34. static double lambda_f_dur = 10;
  35. static double lambda_f_change = 1000;
  36. // pre-calculated parameters for partial function terms:
  37. /**
  38. * Pre calculated for the squash function <br>
  39. * {@link ObjectiveFunctionByCarlos#squash}
  40. */
  41. static double squash_subtract = 100.f / (1.f + (float) Math.exp(5.0));
  42. static double range_for_kappa_f_unre = range(kappa_f_unre);
  43. static double range_for_kappa_f_cool = range(kappa_f_cool);
  44. static double range_for_kappa_f_dur = range(kappa_f_dur);
  45. static {
  46. // init
  47. checkParameter();
  48. }
  49. /**
  50. * Check parameter Setting and print error when wrong values are put in. Here
  51. * should all invariants be placed to be checked on initialization.
  52. */
  53. private static void checkParameter() {
  54. boolean parameterSumOne = Math.abs(w_eb + w_state + w_pro + w_perf + w_holon - 1) < 0.001;
  55. if (!parameterSumOne) {
  56. LOGGER.warning("ParameterError in ObjectiveFunction: w1 + w2 + w3 + w4 + w5 should be 1");
  57. }
  58. }
  59. /**
  60. * ObjectifeFunction by Carlos. Function computes f_g: f_g = w1 * squash(f_eb,
  61. * k1) + w2 * squash(f_state, k2) + w3 * squash(f_pro, k3) + w4 * squash(f_perf,
  62. * k4) + w5 * squash(f_holon, k5)
  63. *
  64. *
  65. * squash is the squashing function {@link ObjectiveFunctionByCarlos#squash}
  66. *
  67. *
  68. * @param state
  69. * @return f_g value between 0 and 100
  70. */
  71. static public double getFitnessValueForState(DecoratedState state) {
  72. // Calculate f_eb the penalty for unbalenced energy in the network
  73. double f_eb = 0;
  74. // sum over all objects
  75. for (DecoratedNetwork net : state.getNetworkList()) {
  76. double netEnergyDifference = 0;
  77. netEnergyDifference += net.getConsumerList().stream()
  78. .map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets())
  79. .reduce(0.f, Float::sum);
  80. netEnergyDifference += net.getConsumerSelfSuppliedList().stream()
  81. .map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets())
  82. .reduce(0.f, Float::sum);
  83. netEnergyDifference += net.getSupplierList().stream()
  84. .map(sup -> sup.getEnergyProducing() - sup.getEnergySelfConsuming()).reduce(0.f, Float::sum);
  85. // abs
  86. f_eb += Math.abs(netEnergyDifference);
  87. }
  88. // Calculate f_state the penalty function for the supply state
  89. double f_state = 0;
  90. for (DecoratedNetwork net : state.getNetworkList()) {
  91. f_state += net.getConsumerList().stream().map(con -> supplyPenalty(con.getSupplyBarPercentage())).reduce(0.,
  92. Double::sum);
  93. }
  94. // calculate f_pro the penalty function for priority usage
  95. // for each active flexibility punish
  96. List<Flexibility> allFlexOrdered = state.getAllFlex().filter(flex -> flex.getState().equals(FlexState.IN_USE))
  97. .toList();
  98. double f_pro = 0;
  99. f_pro = allFlexOrdered.stream()
  100. .map(flex -> Math.pow(theta, priorityToDouble(flex.getElement().getPriority())) - 1.0)
  101. .reduce(0.0, Double::sum);
  102. // calculate f_perf the penalty function for the quality of a flexibility used
  103. // and the subfuction f_unre, f_cool, f_dur
  104. double f_perf = 0;
  105. for (Flexibility flex : allFlexOrdered) {
  106. double f_unre = unresponsivnessPenalty(flex.getSpeed());
  107. double f_cool = cooldownPenalty(flex.getCooldown());
  108. double f_dur = durationPenalty(flex.getDuration());
  109. f_perf += f_unre + f_cool + f_dur;
  110. }
  111. // calculate f_holon
  112. double f_holon = 0;
  113. for (DecoratedNetwork net : state.getNetworkList()) {
  114. double f_elements_diviation_production = net.getDeviationInProductionInNetworkForHolonObjects();
  115. double f_elements_diviation_consumption = net.getDeviationInProductionInNetworkForHolonObjects();
  116. double f_flexibility_diviation_consumption = net.getDiviationInFlexibilityConsumption();
  117. double f_flexibility_diviation_production = net.getDiviationInFlexibilityProduction();
  118. double con = net.getTotalConsumption();
  119. double prod = net.getTotalProduction();
  120. double flexcapProd = net.getFlexibilityProductionCapacity();
  121. double flexcapCon = net.getFlexibilityConsumptionCapacity();
  122. double f_change_positive = lambda_f_change
  123. - lambda_f_change * Math.min(1, (con > 0.0) ? flexcapProd / con : 1.0);
  124. double f_change_negativ = lambda_f_change
  125. - lambda_f_change * Math.min(1, (prod > 0.0) ? flexcapCon / prod : 1.0);
  126. double f_element = f_elements_diviation_production + f_elements_diviation_consumption;
  127. double f_flexibility = f_flexibility_diviation_consumption + f_flexibility_diviation_production;
  128. double f_change = f_change_positive + f_change_negativ;
  129. f_holon += f_element + f_flexibility + f_change;
  130. }
  131. double q1 = squash(f_eb, k_eb);
  132. double q2 = squash(f_state, k_state);
  133. double q3 = squash(f_pro, k_pro);
  134. double q4 = squash(f_perf, k_perf);
  135. double q5 = squash(f_holon, k_holon);
  136. LOGGER.finer("f_eb= " + f_eb + " f_state= " + f_state + " f_pro= " + f_pro + " f_perf= " + f_perf + " f_holon= "
  137. + f_holon + " q1= " + q1 + " q2= " + q2 + " q3= " + q3 + " q4= " + q4 + " q5= " + q5);
  138. return w_eb * q1 + w_state * q2 + w_pro * q3 + w_perf * q4 + w_holon * q5;
  139. }
  140. /**
  141. * The squashing function in paper
  142. *
  143. * @param x the input
  144. * @param kappa the corresponding kappa
  145. * @return
  146. */
  147. static public double squash(double x, double kappa) {
  148. return 100.f / (1.0f + Math.exp(-(10.f * (x - kappa / 2.f)) / kappa)) - squash_subtract;
  149. }
  150. /**
  151. * f_sup in paper
  152. *
  153. * @param supply from 0 to 1
  154. * @return
  155. */
  156. static public double supplyPenalty(double supply) {
  157. double supplyPercentage = 100 * supply;
  158. // double test = (supplyPercentage < 100) ? -0.5 * supplyPercentage + 50:
  159. // supplyPercentage - 100;
  160. return (supplyPercentage < 100) ? -0.5 * supplyPercentage + 50 : supplyPercentage - 100;
  161. }
  162. /**
  163. * prio function in the paper
  164. *
  165. * @param priority
  166. * @return
  167. */
  168. private static double priorityToDouble(Priority priority) {
  169. switch (priority) {
  170. case Essential:
  171. return 3.;
  172. case High:
  173. return 2.;
  174. case Medium:
  175. return 1.;
  176. case Low:
  177. default:
  178. return 0.;
  179. }
  180. }
  181. /**
  182. * Attention Math.log calcultae ln not log
  183. *
  184. * @param kappa
  185. * @return
  186. */
  187. private static double range(double kappa) {
  188. return -kappa / Math.log(Math.pow(2.0, 0.05) - 1.0);
  189. }
  190. /**
  191. * f_unre
  192. *
  193. * @param unresponsiv
  194. * @return
  195. */
  196. private static double unresponsivnessPenalty(double unresponsiv) {
  197. return (2.0 * lambda_f_unre) / (1 + Math.exp(-unresponsiv / range_for_kappa_f_unre)) - lambda_f_unre;
  198. }
  199. /**
  200. * f_cool
  201. *
  202. * @param cooldown
  203. * @return
  204. */
  205. private static double cooldownPenalty(double cooldown) {
  206. return (2.0 * lambda_f_cool) / (1 + Math.exp(-cooldown / range_for_kappa_f_cool)) - lambda_f_cool;
  207. }
  208. private static double durationPenalty(double duration) {
  209. double lambda_dur_times2 = 2.0 * lambda_f_dur;
  210. return -lambda_dur_times2 / (1 + Math.exp(-duration / range_for_kappa_f_dur)) + lambda_dur_times2;
  211. }
  212. }