Holon.java 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. public class Holon {
  9. private static final Logger log = Logger.getLogger(Holon.class.getName());
  10. public Set<HolonObject> holonObjects = new HashSet<>();
  11. public Set<AbstractCanvasObject> objects = new HashSet<>();
  12. public Set<Edge> edges = new HashSet<>();
  13. public Holon(HolonObject holonObject) {
  14. holonObjects.add(holonObject);
  15. objects.add(holonObject);
  16. }
  17. public Holon(Edge edge) {
  18. add(edge);
  19. }
  20. public void add(Edge edge) {
  21. add(edge.getA());
  22. add(edge.getB());
  23. edges.add(edge);
  24. }
  25. public void add(AbstractCanvasObject obj) {
  26. if (obj instanceof HolonObject holonObject) {
  27. holonObjects.add(holonObject);
  28. }
  29. objects.add(obj);
  30. }
  31. public void merge(Holon other) {
  32. holonObjects.addAll(other.holonObjects);
  33. edges.addAll(other.edges);
  34. objects.addAll(other.objects);
  35. other.clear();
  36. }
  37. public void clear() {
  38. holonObjects.clear();
  39. edges.clear();
  40. objects.clear();
  41. }
  42. @Override
  43. public String toString() {
  44. return "[" + objects.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]";
  45. }
  46. public void calculate(int timeStep) {
  47. Map<Boolean, List<HolonObject>> partition = holonObjects.stream().collect(Collectors.partitioningBy(hO -> hO.getActualEnergy() > 0));
  48. List<HolonObject> supplierList = partition.get(true);
  49. List<HolonObject> consumerList = partition.get(false);
  50. // log.info("Supplier [" + supplierList.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
  51. // "Consumer [" + consumerList.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
  52. // );
  53. // Sort SupplierList according to the EnergyToSupplyNetwork maximum first.
  54. supplierList.sort((a, b) -> -Float.compare(a.getActualEnergy(), b.getActualEnergy()));
  55. log.info("Supplier [" + supplierList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
  56. "Consumer [" + consumerList.stream().map(hO -> hO.getName() + hO.getMinimumConsumingElementEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
  57. );
  58. float energyToSupplyInTheNetwork = supplierList.stream()
  59. .map(HolonObject::getActualEnergy)
  60. .reduce(0f, Float::sum);
  61. // STEP 1:
  62. // Supply consuming element first
  63. // Sort ConsumerList according to the MinimumConsumingElementEnergy minimum first.
  64. consumerList.sort((a, b) -> Float.compare(a.getMinimumConsumingElementEnergy(), b.getMinimumConsumingElementEnergy()));
  65. outerLoop:
  66. for (HolonObject con : consumerList) {
  67. for (HolonObject sup : supplierList) {
  68. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  69. if (energyRdyToSupply <= 0.0f) {
  70. continue;
  71. }
  72. float energyNeededForMinimumConsumingElement = con.getMinimumConsumingElementEnergy()
  73. - con.getEnergyFromHolon();
  74. if (energyNeededForMinimumConsumingElement > energyToSupplyInTheNetwork) {
  75. // Dont supply a minimumElement when you cant supply it fully
  76. break outerLoop;
  77. }
  78. if (energyRdyToSupply >= energyNeededForMinimumConsumingElement) {
  79. energyToSupplyInTheNetwork -= energyNeededForMinimumConsumingElement;
  80. supply(con, sup, energyNeededForMinimumConsumingElement);
  81. continue outerLoop;
  82. } else {
  83. energyToSupplyInTheNetwork -= energyRdyToSupply;
  84. supply(con, sup, energyRdyToSupply);
  85. }
  86. }
  87. // No more Energy in the network
  88. break;
  89. }
  90. log.info("Supplier [" + supplierList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
  91. "Consumer [" + consumerList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
  92. );
  93. // STEP 2:
  94. // Supply consumer fully
  95. // Sort ConsumerList according to the EnergyNeeded to supply fully after minimum
  96. // Demand First.
  97. consumerList.sort((l, r) -> Float.compare(
  98. l.getEnergyNeededFromHolon() - l.getEnergyFromHolon(),
  99. r.getEnergyNeededFromHolon() - r.getEnergyFromHolon()));
  100. outerLoop:
  101. for (HolonObject con : consumerList) {
  102. for (HolonObject sup : supplierList) {
  103. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  104. if (energyRdyToSupply <= 0.0f)
  105. continue;
  106. float energyNeededForFullySupply = con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
  107. if (energyNeededForFullySupply <= 0.0f)
  108. continue outerLoop;
  109. if (energyRdyToSupply >= energyNeededForFullySupply) {
  110. energyToSupplyInTheNetwork -= energyNeededForFullySupply;
  111. supply(con, sup, energyNeededForFullySupply);
  112. continue outerLoop;
  113. } else {
  114. energyToSupplyInTheNetwork -= energyRdyToSupply;
  115. supply(con, sup, energyRdyToSupply);
  116. }
  117. }
  118. // No more Energy in the network
  119. break;
  120. }
  121. log.info("energyToSupplyInTheNetwork: " + energyToSupplyInTheNetwork);
  122. if (energyToSupplyInTheNetwork > 0.0f && (consumerList.size() != 0)) {
  123. float equalAmountOfEnergyToSupply = energyToSupplyInTheNetwork
  124. / ((float) (consumerList.size()));
  125. outerLoop:
  126. for (HolonObject con : consumerList) {
  127. for (HolonObject sup : supplierList) {
  128. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  129. if (energyRdyToSupply <= 0.0f)
  130. continue;
  131. float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply
  132. + con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
  133. if (energyRdyToSupply >= energyNeededToSupplyConsumerTheEqualAmount) {
  134. supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
  135. continue outerLoop;
  136. } else {
  137. supply(con, sup, energyRdyToSupply);
  138. }
  139. }
  140. // No more Energy in the network
  141. break;
  142. }
  143. }
  144. holonObjects.forEach(HolonObject::calculateState);
  145. }
  146. private void supply(HolonObject consumer, HolonObject supplier, float energy) {
  147. consumer.setEnergyFromHolon(consumer.getEnergyFromHolon() + energy);
  148. supplier.setEnergyToHolon(supplier.getEnergyToHolon() + energy);
  149. }
  150. }