SimulationManager.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. package ui.controller;
  2. import classes.*;
  3. import ui.model.IntermediateCableWithState;
  4. import ui.model.Consumer;
  5. import ui.model.DecoratedCable;
  6. import ui.model.DecoratedCable.CableState;
  7. import ui.model.DecoratedSwitch.SwitchState;
  8. import ui.model.DecoratedNetwork;
  9. import ui.model.DecoratedState;
  10. import ui.model.DecoratedSwitch;
  11. import ui.model.MinimumModel;
  12. import ui.model.MinimumNetwork;
  13. import ui.model.Model;
  14. import ui.model.Model.FairnessModel;
  15. import ui.model.Passiv;
  16. import ui.model.Supplier;
  17. import ui.model.VisualRepresentationalState;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.HashSet;
  21. import java.util.LinkedList;
  22. import java.util.List;
  23. import java.util.ListIterator;
  24. import java.util.stream.Collectors;
  25. /**
  26. * Controller for Simulation.
  27. *
  28. * @author Gruppe14
  29. */
  30. public class SimulationManager {
  31. int global = 0;
  32. private Model model;
  33. private HashMap<Integer, DecoratedState> saves = new HashMap<Integer, DecoratedState>();
  34. private HashMap<Integer, VisualRepresentationalState> savesVisual = new HashMap<Integer, VisualRepresentationalState>();
  35. private HashMap<Integer, FlexManager> savesFlexManger = new HashMap<Integer, FlexManager>();
  36. private int timeStep;
  37. private HashMap<Holon, ArrayList<Float>> averagesPerHolon;
  38. private HashMap<Holon, ArrayList<Integer>> mergesPerHolon;
  39. private HashMap<Holon, ArrayList<Integer>> splitsPerHolon;
  40. private HashMap<Holon, ArrayList<Integer>> flexesPerHolon;
  41. /**
  42. * Constructor.
  43. *
  44. * @param m
  45. * Model
  46. */
  47. public SimulationManager(Model m) {
  48. model = m;
  49. this.averagesPerHolon = new HashMap<Holon, ArrayList<Float>>();
  50. this.mergesPerHolon = new HashMap<Holon, ArrayList<Integer>>();
  51. this.splitsPerHolon = new HashMap<Holon, ArrayList<Integer>>();
  52. this.flexesPerHolon = new HashMap<Holon, ArrayList<Integer>>();
  53. }
  54. /**
  55. * calculates the flow of the edges and the supply for objects and consider old timesteps for burned cables.
  56. *
  57. * @param timeStep
  58. * current Iteration
  59. * @param updateVisual TODO
  60. */
  61. public void calculateStateForTimeStep(int timeStep, boolean updateVisual) {
  62. // System.out.println("\n=========================================================================\n");
  63. this.timeStep = timeStep;
  64. MinimumModel minimumModel = new MinimumModel(model.getObjectsOnCanvas(), model.getEdgesOnCanvas());
  65. // HashMap<Edge, CableState> map = new HashMap<Edge, CableState>();
  66. // if(timeStep > 0 && saves.containsKey(timeStep-1)) //if the state before exist
  67. // {
  68. //// System.out.println("---------------------------------------");
  69. // //make cable hastmap
  70. // DecoratedState theStateBefore = saves.get(timeStep-1);
  71. // //edges without HolonObjects or burned
  72. // for(DecoratedCable edge : theStateBefore.getLeftOverEdges())
  73. // {
  74. // map.put(edge.getModel(), edge.getState());
  75. // }
  76. // }
  77. //set all the state before:
  78. for(IntermediateCableWithState cable : minimumModel.getEdgeList()) {
  79. // if(map.containsKey(cable.getModel()) && map.get(cable.getModel()) == CableState.Burned) {
  80. // cable.setState(CableState.Burned);
  81. //// System.out.println(cable.getModel()+" burnnnnnnn");
  82. // cable.getModel().setBurned(true);
  83. // }
  84. if(cable.getModel().isBurned()) {
  85. cable.setState(CableState.Burned);
  86. }
  87. }
  88. //compute state of each holon
  89. List<Holon> l = List.copyOf(this.model.getStateHolon().childHolons);
  90. for(Holon h : l) {
  91. h.holonControlUnit.computeState(timeStep);
  92. }
  93. // boolean doesFlexManagerExist = savesFlexManger.containsKey(timeStep);
  94. // boolean createNew = updateVisual || !doesFlexManagerExist;
  95. // FlexManager newFlexManager;
  96. // if(createNew) {
  97. // newFlexManager = new FlexManager(model, timeStep, savesFlexManger.get(timeStep-1));
  98. // if(doesFlexManagerExist) newFlexManager.orderFlexFromList(savesFlexManger.get(timeStep).getAllFlexesOrderedThisTimeStep());
  99. // savesFlexManger.put(timeStep, newFlexManager);
  100. // }else {
  101. // newFlexManager = savesFlexManger.get(timeStep);
  102. // }
  103. ArrayList<MinimumNetwork> list = new ArrayList<MinimumNetwork>();
  104. //for each holarchy get minimum model
  105. ArrayList<MinimumModel> independentHolarchies = new ArrayList<MinimumModel>();
  106. for(Holon h : model.getStateHolon().childHolons) {
  107. independentHolarchies.add(h.getMinimumModel());
  108. }
  109. //set all edges that are not connecting holarchies unnused
  110. HashSet<Edge> e = new HashSet<Edge>();
  111. for(MinimumModel minimumModel2 : independentHolarchies) {
  112. for(IntermediateCableWithState i : minimumModel2.getEdgeList()) {
  113. e.add(i.getModel());
  114. }
  115. }
  116. for(IntermediateCableWithState cable : minimumModel.getEdgeList()) {
  117. if(!e.contains(cable.getModel())) {
  118. cable.setState(CableState.Unused);
  119. }
  120. }
  121. //set all BreakedManuel Cable Burned:
  122. for(IntermediateCableWithState cable : minimumModel.getEdgeList()) {
  123. if(cable.getModel().isBreakedManuel() || cable.getModel().isBurned()) cable.setState(CableState.Burned);
  124. }
  125. ArrayList<IntermediateCableWithState> leftOver = new ArrayList<IntermediateCableWithState>();
  126. boolean doAnotherLoop = true;
  127. while(doAnotherLoop) {
  128. doAnotherLoop = false;
  129. list = calculateNetworks(minimumModel, timeStep, leftOver);
  130. for(MinimumNetwork net : list) {
  131. float energyOnCables = net.getHolonObjectList().stream().filter(object -> object.getEnergyAtTimeStepFlex(timeStep) > 0.0f).map(object -> object.getEnergyAtTimeStepFlex(timeStep)).reduce(0.0f, ((a,b) -> a + b));
  132. // float energyOnCables = net.getHolonObjectList().stream().filter(object -> object.getEnergyAtTimeStepWithFlex(timeStep, newFlexManager) > 0.0f).map(object -> object.getEnergyAtTimeStepWithFlex(timeStep, newFlexManager)).reduce(0.0f, ((a,b) -> a + b));
  133. // float energyOnCables = net.getHolonObjectList().stream().filter(object -> object.getEnergyAtTimeStepFlex(timeStep) > 0.0f).map(object -> object.getEnergyAtTimeStepFlex(timeStep)).reduce(0.0f, ((a,b) -> a + b));
  134. // float energyOnCables = net.getHolonObjectList().stream().filter(object -> object.holon.holonControlUnit.getStateEstimator().getPowerUsage() > 0.0f).map(object -> object.getEnergyAtTimeStepWithFlex(timeStep, newFlexManager)).reduce(0.0f, ((a,b) -> a + b));
  135. //find the cable with the energy supplied from his two connected objects are the biggest, from all cables that the network give more energy than the cablecapacity.
  136. IntermediateCableWithState cable = net.getEdgeList().stream().filter(aCable -> energyOnCables > aCable.getModel().getCapacity() && !aCable.getModel().isUnlimitedCapacity()).max((lhs,rhs) -> Float.compare(lhs.getEnergyFromConnetedAtTimestep(timeStep), rhs.getEnergyFromConnetedAtTimestep(timeStep))).orElse(null);
  137. if(cable != null) {
  138. cable.setState(CableState.Burned);
  139. cable.getModel().setBurned(true);
  140. doAnotherLoop = true;
  141. } else {
  142. net.getEdgeList().stream().forEach(c -> c.getModel().setThroughput(energyOnCables));
  143. }
  144. }
  145. }
  146. //Create lookUpTableForHolonObjetcs
  147. HashMap<HolonObject, DecoratedNetwork> holonObjectNetworkTable = new HashMap<HolonObject, DecoratedNetwork>();
  148. ArrayList<DecoratedNetwork> decorNetworks = new ArrayList<DecoratedNetwork>();
  149. FairnessModel actualFairnessModel = model.getFairnessModel();
  150. for (MinimumNetwork net : list) {
  151. // DecoratedNetwork decNetwork = new DecoratedNetwork(net, timeStep, actualFairnessModel, newFlexManager);
  152. DecoratedNetwork decNetwork = new DecoratedNetwork(net, timeStep, actualFairnessModel);
  153. decorNetworks.add(decNetwork);
  154. for(HolonObject obj : net.getHolonObjectList()) {
  155. holonObjectNetworkTable.put(obj, decNetwork);
  156. }
  157. }
  158. ArrayList<DecoratedCable> leftOverDecoratedCables = new ArrayList<DecoratedCable>();
  159. for(IntermediateCableWithState cable: leftOver) {
  160. leftOverDecoratedCables.add(new DecoratedCable(cable.getModel(), cable.getState(), 0.0f));
  161. }
  162. ArrayList<DecoratedSwitch> listOfDecoratedSwitches = decorateSwitches(minimumModel, timeStep);
  163. DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, timeStep, holonObjectNetworkTable);
  164. saves.put(timeStep, stateFromThisTimestep);
  165. VisualRepresentationalState visualState = new VisualRepresentationalState(stateFromThisTimestep, minimumModel);
  166. if(updateVisual)savesVisual.put(timeStep, visualState);
  167. //Check Holarchy and split Holons if no physical connection is present.
  168. // List<Holon> holonList = model.getStateHolon().childHolons;
  169. // for(int i = 0; i < holonList.size(); i++) {
  170. // holonList.get(i).checkRepairHolarchy(holonObjectNetworkTable, model.getStateHolon());
  171. // }
  172. eval(visualState, independentHolarchies, timeStep >= 99);
  173. }
  174. private void eval(VisualRepresentationalState visualState, ArrayList<MinimumModel> independentHolarchies, boolean print) {
  175. if(print)
  176. System.out.println("\n=========================================================================\n");
  177. //evaluate power usage in each holon object
  178. for(Consumer con : visualState.getConsumerList()) {
  179. evalPower(con.getModel().holon, con.getSupplyBarPercentage(), print);
  180. }
  181. HashMap<MinimumModel, Float> map = new HashMap<>();
  182. for(Supplier sup : visualState.getSupplierList()) {
  183. //find the holarchy where the sup is
  184. MinimumModel holarchy = null;
  185. for(MinimumModel mm : independentHolarchies) {
  186. if(mm.getHolonObjectList().contains(sup.getModel()))
  187. holarchy = mm;
  188. }
  189. //find out how much energy is produced and consumed in total inside this holarchy
  190. //c/p is satisfaction of supplier
  191. float sat = 0f;
  192. if(holarchy != null) {
  193. if(map.containsKey(holarchy)) {
  194. sat = map.get(holarchy);
  195. } else {
  196. float totalProd = 0f;
  197. float totalCon = 0f;
  198. for(HolonObject ho : holarchy.getHolonObjectList()) {
  199. float p = ho.getEnergyAtTimeStepFlex(model.getCurIteration());
  200. if(p > 0) {
  201. totalProd += p;
  202. } else {
  203. totalCon -= p;
  204. }
  205. }
  206. sat = totalCon/totalProd;
  207. map.put(holarchy, sat);
  208. }
  209. }
  210. evalPower(sup.getModel().holon, sat, print);
  211. }
  212. for(Passiv pas : visualState.getPassivList()) {
  213. evalPower(pas.getModel().holon, pas.getEnergy(), print);
  214. }
  215. List<HolonObject> holonObjects = this.model.getAllHolonObjectsOnCanvas();
  216. // int totalMerges = holonObjects.stream().mapToInt(ho -> ho.holon.getMergeCounter()).sum();
  217. // int totalSplits = holonObjects.stream().mapToInt(ho -> ho.holon.getSplitCounter()).sum();
  218. // if(print) {
  219. // System.out.println("Total performed merge: "+totalMerges+"\tavg: "+((float)totalMerges)/((float)holonObjects.size()));
  220. // System.out.println("Total performed split: "+totalSplits+"\tavg: "+((float)totalSplits)/((float)holonObjects.size()));
  221. // }
  222. }
  223. private void evalPower(Holon h, float curr, boolean print) {
  224. ArrayList<Float> avgList = this.averagesPerHolon.getOrDefault(h, new ArrayList<>());
  225. if(timeStep >= avgList.size()) {
  226. avgList.add(curr);
  227. } else {
  228. avgList.remove(timeStep);
  229. avgList.add(timeStep, curr);
  230. }
  231. this.averagesPerHolon.put(h, avgList);
  232. ArrayList<Integer> mergeList = this.mergesPerHolon.getOrDefault(h, new ArrayList<>());
  233. int merges = h.getMergeCounter();// - ((timeStep-1 >= 0 && mergeList.size() > timeStep-1) ? mergeList.get(timeStep-1) : 0);
  234. if(timeStep >= mergeList.size()) {
  235. mergeList.add(merges);
  236. } else {
  237. mergeList.remove(timeStep);
  238. mergeList.add(timeStep, merges);
  239. }
  240. this.mergesPerHolon.put(h, mergeList);
  241. ArrayList<Integer> splitList = this.splitsPerHolon.getOrDefault(h, new ArrayList<>());
  242. int splits = h.getSplitCounter();// - ((timeStep-1 >= 0 && splitList.size() > timeStep-1) ? splitList.get(timeStep-1) : 0);
  243. if(timeStep >= splitList.size()) {
  244. splitList.add(splits);
  245. } else {
  246. splitList.remove(timeStep);
  247. splitList.add(timeStep, splits);
  248. }
  249. this.splitsPerHolon.put(h, splitList);
  250. ArrayList<Integer> flexList = this.flexesPerHolon.getOrDefault(h, new ArrayList<>());
  251. int flexes = h.holonControlUnit.getFlexMan().getAppliedFlexCounter();// - ((timeStep-1 >= 0 && splitList.size() > timeStep-1) ? splitList.get(timeStep-1) : 0);
  252. if(timeStep >= flexList.size()) {
  253. flexList.add(flexes);
  254. } else {
  255. flexList.remove(timeStep);
  256. flexList.add(timeStep, flexes);
  257. }
  258. this.flexesPerHolon.put(h, flexList);
  259. // float avg = 0f;
  260. // for(float f:list)
  261. // avg += f;
  262. // avg = avg/list.size();
  263. float dev = curr-1f;
  264. h.countState(dev);
  265. if(print) {
  266. // System.out.println("next: "+h.getUniqueID()+"\n\tpower stats: "+curr+"\tavg: "+avg+"\t"+list+"\n\tmerges: "+h.getMergeCounter()
  267. // +"\tsplits: "+h.getSplitCounter()+"\n\tDeviation: "+dev+"\t["+h.getStateCounter()[0]+", "+h.getStateCounter()[1]+", "
  268. // +h.getStateCounter()[2]+"]\n\tHolarchy: "
  269. // +h.getMinimumModel().getHolonObjectList().stream().map(ho -> ho.holon.getUniqueID()).collect(Collectors.toList()));
  270. System.out.println("next: "+h.getUniqueID()
  271. +"\n\tpower stats: "+avgList
  272. +"\n\tmerges: "+mergeList
  273. +"\n\tsplits: "+splitList
  274. +"\n\tflexes: "+flexList
  275. +"\n\tstates: ["+h.getStateCounter()[0]+", "+h.getStateCounter()[1]+", "+h.getStateCounter()[2]+"]");
  276. }
  277. }
  278. /**
  279. * Decorate a switch
  280. * @param minModel
  281. * @param iteration
  282. * @return
  283. */
  284. public static ArrayList<DecoratedSwitch> decorateSwitches(MinimumModel minModel, int iteration) {
  285. ArrayList<DecoratedSwitch> aListOfDecoratedSwitches = new ArrayList<DecoratedSwitch>();
  286. for(HolonSwitch hSwitch: minModel.getSwitchList()) {
  287. aListOfDecoratedSwitches.add(new DecoratedSwitch(hSwitch, hSwitch.getState(iteration) ? SwitchState.Closed : SwitchState.Open));
  288. }
  289. return aListOfDecoratedSwitches;
  290. }
  291. /**
  292. * SubFunction to calculate the Networks from the model.
  293. * @param minModel
  294. * @param Iteration
  295. * @param leftOver
  296. * @return
  297. */
  298. ArrayList<MinimumNetwork> calculateNetworks(MinimumModel minModel, int Iteration, ArrayList<IntermediateCableWithState> leftOver){
  299. //Copy minModel ObjectList
  300. ArrayList<HolonObject> holonObjectList = new ArrayList<HolonObject>();
  301. for(HolonObject holonObject: minModel.getHolonObjectList()) {
  302. holonObjectList.add(holonObject);
  303. }
  304. //Copy minModelEdgeList
  305. ArrayList<IntermediateCableWithState> edgeList = new ArrayList<IntermediateCableWithState>();
  306. for(IntermediateCableWithState cable: minModel.getEdgeList()) {
  307. edgeList.add(cable);
  308. }
  309. ArrayList<MinimumNetwork> listOfNetworks = new ArrayList<MinimumNetwork>();
  310. while(!holonObjectList.isEmpty()) {
  311. //lookAt the first holonObject and find his neighbors
  312. HolonObject lookAtObject = holonObjectList.get(0);
  313. //delete out of list
  314. holonObjectList.remove(0);
  315. //create a new Network
  316. MinimumNetwork actualNetwork = new MinimumNetwork(new ArrayList<HolonObject>(), new ArrayList<IntermediateCableWithState>());
  317. actualNetwork.getHolonObjectList().add(lookAtObject);
  318. //create List of neighbors
  319. LinkedList<AbstractCanvasObject> neighbors = new LinkedList<AbstractCanvasObject>();
  320. populateListOfNeighbors(edgeList, lookAtObject, actualNetwork, neighbors);
  321. while(!neighbors.isEmpty()) {
  322. AbstractCanvasObject lookAtNeighbor = neighbors.getFirst();
  323. if(lookAtNeighbor instanceof HolonObject) {
  324. actualNetwork.getHolonObjectList().add((HolonObject) lookAtNeighbor);
  325. holonObjectList.remove(lookAtNeighbor);
  326. }else {
  327. actualNetwork.getNodeAndSwitches().add(lookAtNeighbor);
  328. }
  329. //When HolonSwitch Check if closed
  330. if(!(lookAtNeighbor instanceof HolonSwitch) || ((HolonSwitch)lookAtNeighbor).getState(Iteration)) {
  331. populateListOfNeighbors(edgeList, lookAtNeighbor, actualNetwork, neighbors);
  332. }
  333. neighbors.removeFirst();
  334. }
  335. listOfNetworks.add(actualNetwork);
  336. }
  337. if(leftOver!= null) {
  338. leftOver.clear();
  339. for(IntermediateCableWithState cable: edgeList) {
  340. leftOver.add(cable);
  341. }
  342. }
  343. return listOfNetworks;
  344. }
  345. /**
  346. * Adds the neighbors.
  347. * @param edgeList
  348. * @param lookAtObject
  349. * @param actualNetwork
  350. * @param neighbors
  351. */
  352. void populateListOfNeighbors(ArrayList<IntermediateCableWithState> edgeList, AbstractCanvasObject lookAtObject,
  353. MinimumNetwork actualNetwork, LinkedList<AbstractCanvasObject> neighbors) {
  354. ListIterator<IntermediateCableWithState> iter = edgeList.listIterator();
  355. while(iter.hasNext())
  356. {
  357. IntermediateCableWithState lookAtEdge = iter.next();
  358. if(lookAtEdge.getState() == CableState.Working && lookAtEdge.getModel().isConnectedTo(lookAtObject)) {
  359. iter.remove();
  360. actualNetwork.getEdgeList().add(lookAtEdge);
  361. //Add neighbar
  362. AbstractCanvasObject edgeNeighbor;
  363. if(lookAtEdge.getModel().getA().equals(lookAtObject)) {
  364. edgeNeighbor = lookAtEdge.getModel().getB();
  365. }else {
  366. edgeNeighbor = lookAtEdge.getModel().getA();
  367. }
  368. if(!neighbors.contains(edgeNeighbor)) {
  369. neighbors.add(edgeNeighbor);
  370. }
  371. }
  372. }
  373. }
  374. public DecoratedState getActualDecorState() {
  375. return getDecorState(timeStep);
  376. }
  377. public VisualRepresentationalState getActualVisualRepresentationalState(){
  378. return savesVisual.getOrDefault(timeStep, null);
  379. }
  380. public FlexManager getActualFlexManager() {
  381. return savesFlexManger.getOrDefault(timeStep, null);
  382. }
  383. public void resetFlexManager(){
  384. savesFlexManger.clear();
  385. }
  386. public void resetFlexManagerForTimeStep(int timestep) {
  387. savesFlexManger.get(timestep).reset();
  388. }
  389. public DecoratedState getDecorState(int timestep) {
  390. return saves.get(timestep);
  391. }
  392. public VisualRepresentationalState getVisualRepresentationalState(int timestep) {
  393. return savesVisual.getOrDefault(timestep, null);
  394. }
  395. }