Holon.java 9.9 KB

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