Holon.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. package holeg.model;
  2. import java.util.HashSet;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Set;
  6. import java.util.logging.Logger;
  7. import java.util.stream.Collectors;
  8. import java.util.stream.Stream;
  9. public class Holon {
  10. private static final Logger log = Logger.getLogger(Holon.class.getName());
  11. public Set<HolonObject> holonObjects = new HashSet<>();
  12. public Set<AbstractCanvasObject> objects = new HashSet<>();
  13. public Set<Edge> edges = new HashSet<>();
  14. public Holon(HolonObject holonObject) {
  15. holonObjects.add(holonObject);
  16. objects.add(holonObject);
  17. }
  18. public Holon(Edge edge) {
  19. add(edge);
  20. }
  21. public void add(Edge edge) {
  22. add(edge.getA());
  23. add(edge.getB());
  24. edges.add(edge);
  25. }
  26. public void add(AbstractCanvasObject obj) {
  27. if (obj instanceof HolonObject holonObject) {
  28. holonObjects.add(holonObject);
  29. }
  30. objects.add(obj);
  31. }
  32. public void merge(Holon other) {
  33. holonObjects.addAll(other.holonObjects);
  34. edges.addAll(other.edges);
  35. objects.addAll(other.objects);
  36. other.clear();
  37. }
  38. public void clear() {
  39. holonObjects.clear();
  40. edges.clear();
  41. objects.clear();
  42. }
  43. @Override
  44. public String toString() {
  45. return "[" + objects.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]";
  46. }
  47. public void calculate(int timeStep) {
  48. Map<Boolean, List<HolonObject>> partition = holonObjects.stream().collect(Collectors.partitioningBy(hO -> hO.getActualEnergy() > 0));
  49. List<HolonObject> supplierList = partition.get(true);
  50. List<HolonObject> consumerList = partition.get(false);
  51. supplierList.sort((a, b) -> -Float.compare(a.getActualEnergy(), b.getActualEnergy()));
  52. log.info("Supplier [" + supplierList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
  53. "Consumer [" + consumerList.stream().map(hO -> hO.getName() + hO.getMinimumConsumingElementEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
  54. );
  55. float energyToSupplyInTheNetwork = supplierList.stream()
  56. .map(HolonObject::getActualEnergy)
  57. .reduce(0f, Float::sum);
  58. // STEP 1:
  59. // Supply consuming element first
  60. // Sort ConsumerList according to the MinimumConsumingElementEnergy minimum first.
  61. consumerList.sort((a, b) -> Float.compare(a.getMinimumConsumingElementEnergy(), b.getMinimumConsumingElementEnergy()));
  62. outerLoop:
  63. for (HolonObject con : consumerList) {
  64. for (HolonObject sup : supplierList) {
  65. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  66. if (energyRdyToSupply <= 0.0f) {
  67. continue;
  68. }
  69. float energyNeededForMinimumConsumingElement = con.getMinimumConsumingElementEnergy()
  70. - con.getEnergyFromHolon();
  71. if (energyNeededForMinimumConsumingElement > energyToSupplyInTheNetwork) {
  72. // Dont supply a minimumElement when you cant supply it fully
  73. break outerLoop;
  74. }
  75. if (energyRdyToSupply >= energyNeededForMinimumConsumingElement) {
  76. energyToSupplyInTheNetwork -= energyNeededForMinimumConsumingElement;
  77. supply(con, sup, energyNeededForMinimumConsumingElement);
  78. continue outerLoop;
  79. } else {
  80. energyToSupplyInTheNetwork -= energyRdyToSupply;
  81. supply(con, sup, energyRdyToSupply);
  82. }
  83. }
  84. // No more Energy in the network
  85. break;
  86. }
  87. log.info("Supplier [" + supplierList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
  88. "Consumer [" + consumerList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
  89. );
  90. // STEP 2:
  91. // Supply consumer fully
  92. // Sort ConsumerList according to the EnergyNeeded to supply fully after minimum
  93. // Demand First.
  94. consumerList.sort((l, r) -> Float.compare(
  95. l.getEnergyNeededFromHolon() - l.getEnergyFromHolon(),
  96. r.getEnergyNeededFromHolon() - r.getEnergyFromHolon()));
  97. outerLoop:
  98. for (HolonObject con : consumerList) {
  99. for (HolonObject sup : supplierList) {
  100. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  101. if (energyRdyToSupply <= 0.0f)
  102. continue;
  103. float energyNeededForFullySupply = con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
  104. if (energyNeededForFullySupply <= 0.0f)
  105. continue outerLoop;
  106. if (energyRdyToSupply >= energyNeededForFullySupply) {
  107. energyToSupplyInTheNetwork -= energyNeededForFullySupply;
  108. supply(con, sup, energyNeededForFullySupply);
  109. continue outerLoop;
  110. } else {
  111. energyToSupplyInTheNetwork -= energyRdyToSupply;
  112. supply(con, sup, energyRdyToSupply);
  113. }
  114. }
  115. // No more Energy in the network
  116. break;
  117. }
  118. // STEP 3:
  119. // If energy is still left, oversupply
  120. if (energyToSupplyInTheNetwork > 0.0f && (consumerList.size() != 0)) {
  121. float equalAmountOfEnergyToSupply = energyToSupplyInTheNetwork
  122. / ((float) (consumerList.size()));
  123. outerLoop:
  124. for (HolonObject con : consumerList) {
  125. for (HolonObject sup : supplierList) {
  126. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  127. if (energyRdyToSupply <= 0.0f)
  128. continue;
  129. float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply
  130. + con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
  131. if (energyRdyToSupply >= energyNeededToSupplyConsumerTheEqualAmount) {
  132. supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
  133. continue outerLoop;
  134. } else {
  135. supply(con, sup, energyRdyToSupply);
  136. }
  137. }
  138. // No more Energy in the network
  139. break;
  140. }
  141. }
  142. holonObjects.forEach(HolonObject::calculateState);
  143. }
  144. private void supply(HolonObject consumer, HolonObject supplier, float energy) {
  145. consumer.setEnergyFromHolon(consumer.getEnergyFromHolon() + energy);
  146. supplier.setEnergyToHolon(supplier.getEnergyToHolon() + energy);
  147. }
  148. public Stream<Float> getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork() {
  149. return holonObjects.stream().flatMap(HolonObject::elementsStream)
  150. .filter(ele -> (ele.flexList.stream().anyMatch(flex -> flex.offered)))
  151. .map(ele -> -ele.getActualEnergy());
  152. }
  153. public Stream<Float> getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork() {
  154. return getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork().filter(value -> (value > 0.f));
  155. }
  156. public Stream<Float> getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork() {
  157. return getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork().filter(value -> (value < 0.f))
  158. .map(value -> -value);
  159. }
  160. public float getFlexibilityProductionCapacity() {
  161. return getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork().reduce(0.f, Float::sum);
  162. }
  163. public float getFlexibilityConsumptionCapacity() {
  164. return getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork().reduce(0.f, Float::sum);
  165. }
  166. public int getAmountOfProductionFlexibilities() {
  167. return (int)getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork().count();
  168. }
  169. public int getAmountOfConsumptionFlexibilities() {
  170. return (int)getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork().count();
  171. }
  172. public float getAverageFlexibilityProduction() {
  173. int amount = getAmountOfProductionFlexibilities();
  174. return (amount > 0) ? getFlexibilityProductionCapacity() / (float) amount : 0.f;
  175. }
  176. public float getAverageFlexibilityConsumption() {
  177. int amount = getAmountOfConsumptionFlexibilities();
  178. return (amount > 0) ? getFlexibilityConsumptionCapacity() / (float) amount : 0.f;
  179. }
  180. public float getVarianzInFlexibilitiesConsumption() {
  181. float average = getAverageFlexibilityConsumption();
  182. float sum = getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork()
  183. .map(energy -> squared(energy - average)).reduce(0.f, Float::sum);
  184. int amountOfFlexibilities = getAmountOfConsumptionFlexibilities();
  185. return (amountOfFlexibilities > 0) ? sum / (float) amountOfFlexibilities : 0.f;
  186. }
  187. public float getVarianzInFlexibilitieProduction() {
  188. float average = getAverageFlexibilityProduction();
  189. float sum = getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork()
  190. .map(energy -> squared(energy - average)).reduce(0.f, Float::sum);
  191. int amountOfFlexibilities = getAmountOfProductionFlexibilities();
  192. return (amountOfFlexibilities > 0) ? sum / (float) amountOfFlexibilities : 0.f;
  193. }
  194. public float getDiviationInFlexibilityConsumption() {
  195. return (float) Math.sqrt(getVarianzInFlexibilitiesConsumption());
  196. }
  197. public float getDiviationInFlexibilityProduction() {
  198. return (float) Math.sqrt(getVarianzInFlexibilitieProduction());
  199. }
  200. public float getTotalConsumption() {
  201. return holonObjects.stream().map(HolonObject::getConsumption).reduce(0.f, Float::sum);
  202. }
  203. public float getAverageConsumptionInNetworkForHolonObject() {
  204. return getTotalConsumption() / (float) holonObjects.size();
  205. }
  206. public float getTotalProduction() {
  207. return holonObjects.stream().map(HolonObject::getProduction).reduce(0.f, Float::sum);
  208. }
  209. public float getAverageProductionInNetworkForHolonObject() {
  210. return getTotalProduction() / (float) holonObjects.size();
  211. }
  212. /**
  213. * returns the Varianz in Poduction
  214. *
  215. * @return
  216. */
  217. public float getVarianzInProductionInNetworkForHolonObjects() {
  218. float average = getAverageProductionInNetworkForHolonObject();
  219. float sum = holonObjects.stream().map(hO -> squared(hO.getProduction() - average)).reduce(0.f, Float::sum);
  220. return sum / (float) holonObjects.size();
  221. }
  222. public float getDeviationInProductionInNetworkForHolonObjects() {
  223. return (float) Math.sqrt(getVarianzInProductionInNetworkForHolonObjects());
  224. }
  225. public float getVarianzInConsumptionInNetworkForHolonObjects() {
  226. float average = getAverageConsumptionInNetworkForHolonObject();
  227. float sum = holonObjects.stream().map(hO -> squared(hO.getConsumption() - average)).reduce(0.f, Float::sum);
  228. return sum / (float) holonObjects.size();
  229. }
  230. public float getDeviationInConsumptionInNetworkForHolonObjects() {
  231. return (float) Math.sqrt(getVarianzInConsumptionInNetworkForHolonObjects());
  232. }
  233. // Help Function
  234. private float squared(float input) {
  235. return input * input;
  236. }
  237. public int getAmountOfElements() {
  238. return (int) holonObjects.stream().flatMap(HolonObject::elementsStream).count();
  239. }
  240. }