SimulationManager.java 5.7 KB

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