ObjectiveFunctionByCarlos.java 8.2 KB

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