SimulationManager.java 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package holeg.ui.controller;
  2. import holeg.model.AbstractCanvasObject;
  3. import holeg.model.Edge;
  4. import holeg.model.Edge.EdgeState;
  5. import holeg.model.HolonObject;
  6. import holeg.model.HolonSwitch;
  7. import holeg.model.HolonSwitch.SwitchState;
  8. import holeg.model.Holon;
  9. import holeg.model.Model;
  10. import java.util.*;
  11. import java.util.logging.Logger;
  12. import java.util.stream.Collectors;
  13. public class SimulationManager {
  14. private static final Logger log = Logger.getLogger(SimulationManager.class.getName());
  15. private final Control control;
  16. public SimulationManager(Control control) {
  17. log.fine("Construct SimulationManager");
  18. this.control = control;
  19. }
  20. public void calculateStateForTimeStep(int timeStep) {
  21. log.fine("Calculate");
  22. long start = System.currentTimeMillis();
  23. Model model = control.getModel();
  24. model.getCanvas().getAllSwitchObjectsRecursive().forEach(sw -> sw.calculateState(timeStep));
  25. List<HolonObject> holonObjectList = model.getCanvas().getAllHolonObjectsRecursive().collect(Collectors.toList());
  26. List<Edge> edgeList = new ArrayList<>(model.getEdgesOnCanvas());
  27. Set<Holon> holons = getHolons(holonObjectList, edgeList, timeStep);
  28. holons.forEach(holon -> holon.calculate(timeStep));
  29. model.holons = holons;
  30. log.info("Holons:" + holons.stream().map(Object::toString).collect(Collectors.joining("\n")));
  31. long end = System.currentTimeMillis();
  32. log.finer("Simulation: " + (end - start) + "ms");
  33. }
  34. private Set<Holon> getHolons(List<HolonObject> holonObjectList, List<Edge> edgeList, int timeStep) {
  35. log.info(System.lineSeparator() + "Supplier [" + holonObjectList.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
  36. "Consumer [" + edgeList.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
  37. );
  38. Set<Holon> holons = new HashSet<>();
  39. for (Holon holon : calculateHolonStructure(holonObjectList, edgeList)) {
  40. final float energyOnCables = holon.holonObjects.stream().map(hO -> {
  41. hO.calculateEnergy(timeStep);
  42. return hO.getActualEnergy();
  43. })
  44. .filter(energy -> energy > 0.0f).reduce(0.0f, (Float::sum));
  45. // find the edge with the energy supplied from his two connected objects are
  46. // the biggest, from all cables that the network give more energy than the
  47. // edge capacity.
  48. Optional<Edge> edge = holon.edges.stream()
  49. .filter(e -> energyOnCables > e.maxCapacity && e.mode == Edge.EdgeMode.Normal)
  50. .max((lhs, rhs) -> Float.compare(lhs.getEnergyFromConneted(), rhs.getEnergyFromConneted()));
  51. edge.ifPresentOrElse(e -> {
  52. //Burn Cable
  53. e.setState(EdgeState.Burned);
  54. e.setActualFlow(0.0f);
  55. //Split Holon
  56. holons.addAll(getHolons(new ArrayList<>(holon.holonObjects), new ArrayList<>(holon.edges), timeStep));
  57. }, () -> {
  58. holon.edges.forEach(e -> e.setActualFlow(energyOnCables));
  59. holons.add(holon);
  60. });
  61. }
  62. return holons;
  63. }
  64. Set<Holon> calculateHolonStructure(List<HolonObject> holonObjectList, List<Edge> edgeList) {
  65. Set<Holon> holons = new HashSet<>();
  66. while (!holonObjectList.isEmpty()) {
  67. // lookAt the first holonObject and find his neighbors
  68. HolonObject lookAtObject = holonObjectList.get(0);
  69. // delete out of list
  70. holonObjectList.remove(0);
  71. // create a new Network
  72. Holon actualNetwork = new Holon(lookAtObject);
  73. // create List of neighbors
  74. LinkedList<AbstractCanvasObject> neighbors = new LinkedList<>();
  75. populateListOfNeighbors(edgeList, lookAtObject, actualNetwork, neighbors);
  76. while (!neighbors.isEmpty()) {
  77. AbstractCanvasObject lookAtNeighbor = neighbors.getFirst();
  78. if (lookAtNeighbor instanceof HolonObject) {
  79. holonObjectList.remove(lookAtNeighbor);
  80. }
  81. actualNetwork.add(lookAtNeighbor);
  82. // When HolonSwitch Check if closed
  83. if (!(lookAtNeighbor instanceof HolonSwitch sw) || sw.getState() == SwitchState.Closed) {
  84. populateListOfNeighbors(edgeList, lookAtNeighbor, actualNetwork, neighbors);
  85. }
  86. neighbors.removeFirst();
  87. }
  88. holons.add(actualNetwork);
  89. }
  90. for (Edge e : edgeList) {
  91. e.setActualFlow(0.0f);
  92. }
  93. return holons;
  94. }
  95. /**
  96. * Adds neighbors.
  97. */
  98. void populateListOfNeighbors(List<Edge> edgeList, AbstractCanvasObject lookAtObject,
  99. Holon actualNetwork, LinkedList<AbstractCanvasObject> neighbors) {
  100. ListIterator<Edge> iter = edgeList.listIterator();
  101. while (iter.hasNext()) {
  102. Edge lookAtEdge = iter.next();
  103. if (lookAtEdge.getState() == EdgeState.Working && lookAtEdge.isConnectedTo(lookAtObject)) {
  104. iter.remove();
  105. actualNetwork.edges.add(lookAtEdge);
  106. // Add neighbor
  107. AbstractCanvasObject edgeNeighbor;
  108. if (lookAtEdge.getA().equals(lookAtObject)) {
  109. edgeNeighbor = lookAtEdge.getB();
  110. } else {
  111. edgeNeighbor = lookAtEdge.getA();
  112. }
  113. if (!neighbors.contains(edgeNeighbor)) {
  114. neighbors.add(edgeNeighbor);
  115. }
  116. }
  117. }
  118. }
  119. }