Holon.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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 clear() {
  33. holonObjects.clear();
  34. edges.clear();
  35. objects.clear();
  36. }
  37. @Override
  38. public String toString() {
  39. return "[" + objects.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]";
  40. }
  41. public void calculate() {
  42. Map<Boolean, List<HolonObject>> partition = holonObjects.stream().collect(Collectors.partitioningBy(hO -> hO.getActualEnergy() > 0));
  43. List<HolonObject> supplierList = partition.get(true);
  44. List<HolonObject> consumerList = partition.get(false);
  45. supplierList.sort((a, b) -> -Float.compare(a.getActualEnergy(), b.getActualEnergy()));
  46. float energyToSupplyInTheNetwork = supplierList.stream()
  47. .map(HolonObject::getActualEnergy)
  48. .reduce(0f, Float::sum);
  49. // STEP 1:
  50. // Supply consuming element first
  51. // Sort ConsumerList according to the MinimumConsumingElementEnergy minimum first.
  52. consumerList.sort((a, b) -> Float.compare(a.getMinimumConsumingElementEnergy(), b.getMinimumConsumingElementEnergy()));
  53. outerLoop:
  54. for (HolonObject con : consumerList) {
  55. for (HolonObject sup : supplierList) {
  56. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  57. if (energyRdyToSupply <= 0.0f) {
  58. continue;
  59. }
  60. float energyNeededForMinimumConsumingElement = con.getMinimumConsumingElementEnergy()
  61. - con.getEnergyFromHolon();
  62. if (energyNeededForMinimumConsumingElement > energyToSupplyInTheNetwork) {
  63. // Dont supply a minimumElement when you cant supply it fully
  64. break outerLoop;
  65. }
  66. if (energyRdyToSupply >= energyNeededForMinimumConsumingElement) {
  67. energyToSupplyInTheNetwork -= energyNeededForMinimumConsumingElement;
  68. supply(con, sup, energyNeededForMinimumConsumingElement);
  69. continue outerLoop;
  70. } else {
  71. energyToSupplyInTheNetwork -= energyRdyToSupply;
  72. supply(con, sup, energyRdyToSupply);
  73. }
  74. }
  75. // No more Energy in the network
  76. break;
  77. }
  78. // STEP 2:
  79. // Supply consumer fully
  80. // Sort ConsumerList according to the EnergyNeeded to supply fully after minimum
  81. // Demand First.
  82. consumerList.sort((l, r) -> Float.compare(
  83. l.getEnergyNeededFromHolon() - l.getEnergyFromHolon(),
  84. r.getEnergyNeededFromHolon() - r.getEnergyFromHolon()));
  85. outerLoop:
  86. for (HolonObject con : consumerList) {
  87. for (HolonObject sup : supplierList) {
  88. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  89. if (energyRdyToSupply <= 0.0f)
  90. continue;
  91. float energyNeededForFullySupply = con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
  92. if (energyNeededForFullySupply <= 0.0f)
  93. continue outerLoop;
  94. if (energyRdyToSupply >= energyNeededForFullySupply) {
  95. energyToSupplyInTheNetwork -= energyNeededForFullySupply;
  96. supply(con, sup, energyNeededForFullySupply);
  97. continue outerLoop;
  98. } else {
  99. energyToSupplyInTheNetwork -= energyRdyToSupply;
  100. supply(con, sup, energyRdyToSupply);
  101. }
  102. }
  103. // No more Energy in the network
  104. break;
  105. }
  106. // STEP 3:
  107. // If energy is still left, oversupply
  108. if (energyToSupplyInTheNetwork > 0.0f && (consumerList.size() != 0)) {
  109. float equalAmountOfEnergyToSupply = energyToSupplyInTheNetwork
  110. / ((float) (consumerList.size()));
  111. outerLoop:
  112. for (HolonObject con : consumerList) {
  113. for (HolonObject sup : supplierList) {
  114. float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
  115. if (energyRdyToSupply <= 0.0f)
  116. continue;
  117. float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply
  118. + con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
  119. if (energyRdyToSupply >= energyNeededToSupplyConsumerTheEqualAmount) {
  120. supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
  121. continue outerLoop;
  122. } else {
  123. supply(con, sup, energyRdyToSupply);
  124. }
  125. }
  126. // No more Energy in the network
  127. break;
  128. }
  129. }
  130. holonObjects.forEach(HolonObject::calculateState);
  131. }
  132. private void supply(HolonObject consumer, HolonObject supplier, float energy) {
  133. consumer.setEnergyFromHolon(consumer.getEnergyFromHolon() + energy);
  134. supplier.setEnergyToHolon(supplier.getEnergyToHolon() + energy);
  135. }
  136. public Stream<Float> getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork() {
  137. return holonObjects.stream().flatMap(HolonObject::elementsStream)
  138. .filter(ele -> (ele.flexList.stream().anyMatch(flex -> flex.offered)))
  139. .map(ele -> -ele.getActualEnergy());
  140. }
  141. public Stream<Float> getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork() {
  142. return getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork().filter(value -> (value > 0.f));
  143. }
  144. public Stream<Float> getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork() {
  145. return getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork().filter(value -> (value < 0.f))
  146. .map(value -> -value);
  147. }
  148. public float getFlexibilityProductionCapacity() {
  149. return getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork().reduce(0.f, Float::sum);
  150. }
  151. public float getFlexibilityConsumptionCapacity() {
  152. return getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork().reduce(0.f, Float::sum);
  153. }
  154. public int getAmountOfProductionFlexibilities() {
  155. return (int)getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork().count();
  156. }
  157. public int getAmountOfConsumptionFlexibilities() {
  158. return (int)getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork().count();
  159. }
  160. public float getAverageFlexibilityProduction() {
  161. int amount = getAmountOfProductionFlexibilities();
  162. return (amount > 0) ? getFlexibilityProductionCapacity() / (float) amount : 0.f;
  163. }
  164. public float getAverageFlexibilityConsumption() {
  165. int amount = getAmountOfConsumptionFlexibilities();
  166. return (amount > 0) ? getFlexibilityConsumptionCapacity() / (float) amount : 0.f;
  167. }
  168. public float getVarianceInFlexibilitiesConsumption() {
  169. float average = getAverageFlexibilityConsumption();
  170. float sum = getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork()
  171. .map(energy -> squared(energy - average)).reduce(0.f, Float::sum);
  172. int amountOfFlexibilities = getAmountOfConsumptionFlexibilities();
  173. return (amountOfFlexibilities > 0) ? sum / (float) amountOfFlexibilities : 0.f;
  174. }
  175. public float getVarianceInFlexibilityProduction() {
  176. float average = getAverageFlexibilityProduction();
  177. float sum = getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork()
  178. .map(energy -> squared(energy - average)).reduce(0.f, Float::sum);
  179. int amountOfFlexibilities = getAmountOfProductionFlexibilities();
  180. return (amountOfFlexibilities > 0) ? sum / (float) amountOfFlexibilities : 0.f;
  181. }
  182. public float getDeviationInFlexibilityConsumption() {
  183. return (float) Math.sqrt(getVarianceInFlexibilitiesConsumption());
  184. }
  185. public float getDeviationInFlexibilityProduction() {
  186. return (float) Math.sqrt(getVarianceInFlexibilityProduction());
  187. }
  188. public float getTotalConsumption() {
  189. return holonObjects.stream().map(HolonObject::getConsumption).reduce(0.f, Float::sum);
  190. }
  191. public float getAverageConsumptionInNetworkForHolonObject() {
  192. return getTotalConsumption() / (float) holonObjects.size();
  193. }
  194. public float getTotalProduction() {
  195. return holonObjects.stream().map(HolonObject::getProduction).reduce(0.f, Float::sum);
  196. }
  197. public float getAverageProductionInNetworkForHolonObject() {
  198. return getTotalProduction() / (float) holonObjects.size();
  199. }
  200. /**
  201. * returns the Varianz in Poduction
  202. *
  203. */
  204. public float getVarianceInProductionInNetworkForHolonObjects() {
  205. float average = getAverageProductionInNetworkForHolonObject();
  206. float sum = holonObjects.stream().map(hO -> squared(hO.getProduction() - average)).reduce(0.f, Float::sum);
  207. return sum / (float) holonObjects.size();
  208. }
  209. public float getDeviationInProductionInNetworkForHolonObjects() {
  210. return (float) Math.sqrt(getVarianceInProductionInNetworkForHolonObjects());
  211. }
  212. public float getVarianceInConsumptionInNetworkForHolonObjects() {
  213. float average = getAverageConsumptionInNetworkForHolonObject();
  214. float sum = holonObjects.stream().map(hO -> squared(hO.getConsumption() - average)).reduce(0.f, Float::sum);
  215. return sum / (float) holonObjects.size();
  216. }
  217. public float getDeviationInConsumptionInNetworkForHolonObjects() {
  218. return (float) Math.sqrt(getVarianceInConsumptionInNetworkForHolonObjects());
  219. }
  220. // Help Function
  221. private float squared(float input) {
  222. return input * input;
  223. }
  224. public int getAmountOfElements() {
  225. return (int) holonObjects.stream().flatMap(HolonObject::elementsStream).count();
  226. }
  227. }