ObjectiveFunctionByCarlos.java 7.3 KB

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