SimulationManager.java 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. package ui.controller;
  2. import classes.*;
  3. import classes.comparator.EnergyMinToMaxComparator;
  4. import classes.comparator.MinEnergyComparator;
  5. import classes.comparator.WeakestBattery;
  6. import ui.model.CableWithState;
  7. import ui.model.DecoratedCable;
  8. import ui.model.DecoratedCable.CableState;
  9. import ui.model.DecoratedSwitch.SwitchState;
  10. import ui.model.DecoratedNetwork;
  11. import ui.model.DecoratedState;
  12. import ui.model.DecoratedSwitch;
  13. import ui.model.MinimumModel;
  14. import ui.model.MinimumNetwork;
  15. import ui.model.Model;
  16. import ui.model.Model.FairnessModel;
  17. import ui.model.VisualRepresentationalState;
  18. import ui.view.FlexiblePane;
  19. import ui.view.GUI;
  20. import ui.view.MyCanvas;
  21. import ui.view.Outliner;
  22. import java.util.ArrayList;
  23. import java.util.Collections;
  24. import java.util.HashMap;
  25. import java.util.LinkedList;
  26. import java.util.ListIterator;
  27. import javax.swing.JPanel;
  28. /**
  29. * Controller for Simulation.
  30. *
  31. * @author Gruppe14
  32. */
  33. public class SimulationManager {
  34. int global = 0;
  35. private Model model;
  36. private ArrayList<AbstractCpsObject> objectsToHandle;
  37. private ArrayList<SubNet> subNets;
  38. private ArrayList<CpsEdge> brokenEdges;
  39. private HashMap<Integer, DecoratedState> saves = new HashMap<Integer, DecoratedState>();
  40. private HashMap<Integer, VisualRepresentationalState> savesVisual = new HashMap<Integer, VisualRepresentationalState>();
  41. private MyCanvas canvas;
  42. private int timeStep;
  43. private HashMap<Integer, Float> tagTable = new HashMap<>();
  44. private FlexiblePane flexPane;
  45. private GUI gui;
  46. private HashMap<HolonElement, Float> flexDevicesTurnedOnThisTurn = new HashMap<>();
  47. /**
  48. * Constructor.
  49. *
  50. * @param m
  51. * Model
  52. */
  53. SimulationManager(Model m) {
  54. canvas = null;
  55. model = m;
  56. subNets = new ArrayList<>();
  57. brokenEdges = new ArrayList<>();
  58. }
  59. /**
  60. * calculates the flow of the edges and the supply for objects and consider old timesteps for burned cables.
  61. *
  62. * @param timestep
  63. * current Iteration
  64. */
  65. void calculateStateForTimeStep(int timestep) {
  66. HashMap<CpsEdge, CableState> map = new HashMap<CpsEdge, CableState>();
  67. if(timestep > 0 && saves.containsKey(timestep-1)) //if the state before exist
  68. {
  69. //make cable hastmap
  70. DecoratedState theStateBefore = saves.get(timestep-1);
  71. for(DecoratedCable edge : theStateBefore.getLeftOverEdges())
  72. {
  73. map.put(edge.getModel(), edge.getState());
  74. }
  75. }
  76. timeStep = timestep;
  77. ArrayList<MinimumNetwork> list = new ArrayList<MinimumNetwork>();
  78. MinimumModel minimumModel = new MinimumModel(model.getObjectsOnCanvas(), model.getEdgesOnCanvas());
  79. //set all working:
  80. for(CableWithState cable : minimumModel.getEdgeList()) {
  81. if(map.containsKey(cable.getModel())) cable.setState(map.get(cable.getModel()));
  82. }
  83. ArrayList<CableWithState> leftOver = new ArrayList<CableWithState>();
  84. boolean doAnotherLoop = true;
  85. while(doAnotherLoop) {
  86. doAnotherLoop = false;
  87. list = calculateNetworks(minimumModel, timestep, leftOver);
  88. for(MinimumNetwork net : list) {
  89. float energyOnCables = net.getHolonObjectList().stream().filter(object -> object.getEnergyAtTimeStep(timestep) > 0.0f).map(object -> object.getEnergyAtTimeStep(timestep)).reduce(0.0f, ((a,b) -> a + b));
  90. //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.
  91. CableWithState cable = net.getEdgeList().stream().filter(aCable -> energyOnCables > aCable.getModel().getCapacity()).max((lhs,rhs) -> Float.compare(lhs.getEnergyFromConnetedAtTimestep(timestep), rhs.getEnergyFromConnetedAtTimestep(timestep))).orElse(null);
  92. if(cable != null) {
  93. cable.setState(CableState.Burned);
  94. doAnotherLoop = true;
  95. }
  96. }
  97. }
  98. ArrayList<DecoratedNetwork> decorNetworks = new ArrayList<DecoratedNetwork>();
  99. FairnessModel actualFairnessModel = model.getFairnessModel();
  100. for (MinimumNetwork net : list) {
  101. decorNetworks.add(new DecoratedNetwork(net, timestep, actualFairnessModel));
  102. }
  103. ArrayList<DecoratedCable> leftOverDecoratedCables = new ArrayList<DecoratedCable>();
  104. for(CableWithState cable: leftOver) {
  105. leftOverDecoratedCables.add(new DecoratedCable(cable.getModel(), cable.getState(), 0.0f));
  106. }
  107. ArrayList<DecoratedSwitch> listOfDecoratedSwitches = decorateSwitches(minimumModel, timestep);
  108. DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, timestep);
  109. saves.put(timestep, stateFromThisTimestep);
  110. savesVisual.put(timestep, new VisualRepresentationalState(stateFromThisTimestep, minimumModel));
  111. canvas.repaint();
  112. gui.updateOutliners(getActualDecorState());//saves.getOrDefault(timestep, null);
  113. }
  114. /**
  115. * Decorate a switch
  116. * @param minModel
  117. * @param iteration
  118. * @return
  119. */
  120. public static ArrayList<DecoratedSwitch> decorateSwitches(MinimumModel minModel, int iteration) {
  121. ArrayList<DecoratedSwitch> aListOfDecoratedSwitches = new ArrayList<DecoratedSwitch>();
  122. for(HolonSwitch hSwitch: minModel.getSwitchList()) {
  123. aListOfDecoratedSwitches.add(new DecoratedSwitch(hSwitch, hSwitch.getState(iteration) ? SwitchState.Closed : SwitchState.Open));
  124. }
  125. return aListOfDecoratedSwitches;
  126. }
  127. /**
  128. * SubFunction to calculate the Networks from the model.
  129. * @param minModel
  130. * @param Iteration
  131. * @param leftOver
  132. * @return
  133. */
  134. ArrayList<MinimumNetwork> calculateNetworks(MinimumModel minModel, int Iteration, ArrayList<CableWithState> leftOver){
  135. //Copy minModel ObjectList
  136. ArrayList<HolonObject> holonObjectList = new ArrayList<HolonObject>();
  137. for(HolonObject holonObject: minModel.getHolonObjectList()) {
  138. holonObjectList.add(holonObject);
  139. }
  140. //Copy minModelEdgeList
  141. ArrayList<CableWithState> edgeList = new ArrayList<CableWithState>();
  142. for(CableWithState cable: minModel.getEdgeList()) {
  143. edgeList.add(cable);
  144. }
  145. ArrayList<MinimumNetwork> listOfNetworks = new ArrayList<MinimumNetwork>();
  146. while(!holonObjectList.isEmpty()) {
  147. //lookAt the first holonObject and find his neighbors
  148. HolonObject lookAtObject = holonObjectList.get(0);
  149. //delete out of list
  150. holonObjectList.remove(0);
  151. //create a new Network
  152. MinimumNetwork actualNetwork = new MinimumNetwork(new ArrayList<HolonObject>(), new ArrayList<CableWithState>());
  153. actualNetwork.getHolonObjectList().add(lookAtObject);
  154. //create List of neighbors
  155. LinkedList<AbstractCpsObject> neighbors = new LinkedList<AbstractCpsObject>();
  156. populateListOfNeighbors(edgeList, lookAtObject, actualNetwork, neighbors);
  157. while(!neighbors.isEmpty()) {
  158. AbstractCpsObject lookAtNeighbor = neighbors.getFirst();
  159. if(lookAtNeighbor instanceof HolonObject) {
  160. actualNetwork.getHolonObjectList().add((HolonObject) lookAtNeighbor);
  161. holonObjectList.remove(lookAtNeighbor);
  162. }
  163. //When HolonSwitch Check if closed
  164. if(!(lookAtNeighbor instanceof HolonSwitch) || ((HolonSwitch)lookAtNeighbor).getState(Iteration)) {
  165. populateListOfNeighbors(edgeList, lookAtNeighbor, actualNetwork, neighbors);
  166. }
  167. neighbors.removeFirst();
  168. }
  169. listOfNetworks.add(actualNetwork);
  170. }
  171. if(leftOver!= null) {
  172. leftOver.clear();
  173. for(CableWithState cable: edgeList) {
  174. leftOver.add(cable);
  175. }
  176. }
  177. return listOfNetworks;
  178. }
  179. /**
  180. * Adds the neighbors.
  181. * @param edgeList
  182. * @param lookAtObject
  183. * @param actualNetwork
  184. * @param neighbors
  185. */
  186. void populateListOfNeighbors(ArrayList<CableWithState> edgeList, AbstractCpsObject lookAtObject,
  187. MinimumNetwork actualNetwork, LinkedList<AbstractCpsObject> neighbors) {
  188. ListIterator<CableWithState> iter = edgeList.listIterator();
  189. while(iter.hasNext())
  190. {
  191. CableWithState lookAtEdge = iter.next();
  192. if(lookAtEdge.getState() == CableState.Working && lookAtEdge.getModel().isConnectedTo(lookAtObject)) {
  193. iter.remove();
  194. actualNetwork.getEdgeList().add(lookAtEdge);
  195. //Add neighbar
  196. AbstractCpsObject edgeNeighbor;
  197. if(lookAtEdge.getModel().getA().equals(lookAtObject)) {
  198. edgeNeighbor = lookAtEdge.getModel().getB();
  199. }else {
  200. edgeNeighbor = lookAtEdge.getModel().getA();
  201. }
  202. if(!neighbors.contains(edgeNeighbor)) {
  203. neighbors.add(edgeNeighbor);
  204. }
  205. }
  206. }
  207. }
  208. /**
  209. * add all battries.getOut() from a list of battries and return them
  210. * @param aL a List of HolonBattries likely from subnet.getBatteries()
  211. * @param x TimeStep
  212. * @return
  213. *
  214. */
  215. private float GetOutAllBatteries(ArrayList<HolonBattery> aL, int x)
  216. {
  217. float OutEnergy = 0;
  218. for(HolonBattery hB : aL)
  219. {
  220. //System.out.println("Iteration: "+ x +"OutBattery: "+ hB.getOutAtTimeStep(x-1));
  221. OutEnergy += hB.getOutAtTimeStep(x-1);
  222. }
  223. //System.out.println("Iteration: "+ x +"GetOutAllBatteries: "+ OutEnergy);
  224. return OutEnergy;
  225. }
  226. /**
  227. * search for all flexible devices in the network and turn them on, until
  228. * energy surplus = 0 or all devices have been examined.
  229. *
  230. * This code could be compressed (cases inside over- and underproduction are
  231. * the same), but we decided that it is better readable this way
  232. *
  233. * @param subNet
  234. * the subnet
  235. * @param energySurplus
  236. * the current surplus of energy
  237. */
  238. private void turnOnFlexibleDevices(SubNet subNet, float energySurplus,
  239. int timestep) {
  240. for (HolonObject holonOb : subNet.getObjects()) {
  241. for (HolonElement holonEl : holonOb.getElements()) {
  242. // if this element is flexible and active (can be considered for
  243. // calculations)
  244. if (holonEl.isFlexible() && holonEl.isActive()) {
  245. float energyAvailableSingle = holonEl
  246. .getEnergyAtTimeStep(timestep);
  247. float energyAvailableMultiple = energyAvailableSingle
  248. * holonEl.getAmount();
  249. // ------------- flexible consumer / OVERPRODUCTION
  250. // -------------
  251. if (energyAvailableMultiple < 0 && energySurplus > 0) {
  252. // if there is more wasted energy than energy that this
  253. // device can give, give all energy available
  254. if (Math.abs(energyAvailableMultiple) <= Math
  255. .abs(energySurplus)) {
  256. energySurplus += energyAvailableMultiple;
  257. // set the new energy consumption to the maximum
  258. holonEl.setEnergyPerElement(energyAvailableSingle);
  259. flexDevicesTurnedOnThisTurn.put(holonEl,
  260. energyAvailableMultiple);
  261. }
  262. // else: we just need to turn on part of the flexible
  263. // energy available
  264. else {
  265. float energyNeeded = -energySurplus;
  266. energySurplus += energyNeeded; // should give 0, but
  267. // was kept this was
  268. // for consistency
  269. // the energy needed divided through the amount of
  270. // elements
  271. holonEl.setEnergyPerElement(energyNeeded
  272. / holonEl.getAmount());
  273. flexDevicesTurnedOnThisTurn.put(holonEl,
  274. energyNeeded);
  275. }
  276. }
  277. // ------------- flexible producer / UNDERPRODUCTION
  278. // -------------
  279. else if (energyAvailableMultiple > 0 && energySurplus < 0) {
  280. // if there is more energy needed than this device can
  281. // give, give all the energy available
  282. if (Math.abs(energyAvailableMultiple) <= Math
  283. .abs(energySurplus)) {
  284. energySurplus += energyAvailableMultiple;
  285. // set the new energy consumption to the maximum
  286. holonEl.setEnergyPerElement(energyAvailableSingle);
  287. flexDevicesTurnedOnThisTurn.put(holonEl,
  288. energyAvailableMultiple);
  289. }
  290. // else: we just need to turn on part of the flexible
  291. // energy available
  292. else {
  293. float energyNeeded = -energySurplus;
  294. int i = 0;
  295. energySurplus += energyNeeded; // should give 0, but
  296. // was kept this was
  297. // for consistency
  298. // the energy needed divided through the amount of
  299. // elements
  300. holonEl.setEnergyPerElement(energyNeeded
  301. / holonEl.getAmount());
  302. flexDevicesTurnedOnThisTurn.put(holonEl,
  303. energyNeeded);
  304. }
  305. }
  306. }
  307. if (energySurplus == 0) {
  308. break;
  309. }
  310. }
  311. if (energySurplus == 0) {
  312. break;
  313. }
  314. }
  315. }
  316. /**
  317. * Set Flow Simulation.
  318. *
  319. * @param sN
  320. * Subnet
  321. */
  322. private void setFlowSimulation(SubNet sN) {
  323. ArrayList<AbstractCpsObject> producers = new ArrayList<>();
  324. AbstractCpsObject tmp = null;
  325. tagTable = new HashMap<>();
  326. // traverse all objects in this subnet
  327. for (HolonObject hl : sN.getObjects()) {
  328. float energy = hl.getEnergyAtTimeStep(timeStep);
  329. // if their production is higher than their consumption
  330. if (energy > 0) {
  331. tagTable.put(hl.getId(), energy);
  332. hl.addTag(hl.getId());
  333. for (CpsEdge edge : hl.getConnections()) {
  334. if (edge.isWorking()) {
  335. // set other end of edge as tmp-object
  336. // and add this end to the other end's tag-list
  337. AbstractCpsObject a = edge.getA();
  338. AbstractCpsObject b = edge.getB();
  339. if (a.getId() == hl.getId()) {
  340. b.addTag(hl.getId());
  341. tmp = b;
  342. }
  343. if (b.getId() == hl.getId()) {
  344. a.addTag(hl.getId());
  345. tmp = a;
  346. }
  347. edge.setFlow(edge.getFlow() + energy);
  348. edge.calculateState();
  349. edge.addTag(hl.getId());
  350. if (edge.isWorking() && !producers.contains(tmp)) {
  351. if (tmp instanceof HolonSwitch) {
  352. if (((HolonSwitch) tmp).getState(timeStep)) {
  353. producers.add(tmp);
  354. }
  355. } else if (!(tmp instanceof CpsUpperNode)) {
  356. producers.add(tmp);
  357. }
  358. }
  359. }
  360. }
  361. }
  362. }
  363. setFlowSimRec(producers, 0);
  364. }
  365. /**
  366. * Set Flow Simulation Rec.
  367. *
  368. * @param nodes
  369. * the nodes
  370. * @param iter
  371. * the Iteration
  372. */
  373. private void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
  374. ArrayList<AbstractCpsObject> newNodes = new ArrayList<>();
  375. ArrayList<CpsEdge> changedEdges = new ArrayList<>();
  376. AbstractCpsObject tmp;
  377. if (nodes.size() != 0) {
  378. for (AbstractCpsObject cps : nodes) {
  379. // check whether the cps is in a legit state if it is a switch
  380. if (legitState(cps)) {
  381. for (CpsEdge edge : cps.getConnections()) {
  382. // is edge working
  383. // and does the edge's tag-list not (yet) contain all
  384. // tags of the cps
  385. if (edge.isWorking()
  386. && (!(edge.containsTags(edge.getTags(),
  387. cps.getTag())))) {
  388. if (edge.getA().getId() == cps.getId()) {
  389. tmp = edge.getB();
  390. } else {
  391. tmp = edge.getA();
  392. }
  393. for (Integer tag : cps.getTag()) {
  394. if (!(edge.getTags().contains(tag))
  395. && !(edge.getPseudoTags().contains(tag))) {
  396. edge.setFlow(edge.getFlow()
  397. + tagTable.get(tag));
  398. edge.addTag(tag);
  399. }
  400. }
  401. // uppernodes do not spread energy
  402. if (!(tmp instanceof CpsUpperNode)) {
  403. for (Integer tag : tmp.getTag()) {
  404. if (!(edge.getTags().contains(tag))
  405. && tagTable.get(tag) != null
  406. && !(edge.getPseudoTags()
  407. .contains(tag))) {
  408. edge.setFlow(edge.getFlow()
  409. + tagTable.get(tag));
  410. edge.addPseudoTag(tag);
  411. changedEdges.add(edge);
  412. }
  413. }
  414. }
  415. edge.calculateState();
  416. if (edge.isWorking()
  417. && !(tmp instanceof CpsUpperNode)) {
  418. tmp.addAllPseudoTags(cps.getTag());
  419. if (!newNodes.contains(tmp)) {
  420. newNodes.add(tmp);
  421. }
  422. }
  423. }
  424. }
  425. }
  426. }
  427. setPseudoTags(newNodes, changedEdges);
  428. setFlowSimRec(newNodes, iter + 1);
  429. }
  430. }
  431. /**
  432. * Set the Pseudo Tags.
  433. *
  434. * @param nodes
  435. * Array of AbstractCpsObjects
  436. */
  437. private void setPseudoTags(ArrayList<AbstractCpsObject> nodes,
  438. ArrayList<CpsEdge> edges) {
  439. for (AbstractCpsObject node : nodes) {
  440. node.recalculateTags();
  441. node.setPseudoTags(new ArrayList<>());
  442. }
  443. for (CpsEdge edge : edges) {
  444. edge.recalculateTags();
  445. edge.setPseudoTag(new ArrayList<>());
  446. }
  447. }
  448. /**
  449. * Reset the Connection.
  450. *
  451. * @param cps
  452. * CpsObject
  453. * @param visitedObj
  454. * the visited Objects
  455. * @param visitedEdges
  456. * the visited Edges
  457. */
  458. private void resetConnections(AbstractCpsObject cps,
  459. ArrayList<Integer> visitedObj, ArrayList<CpsEdge> visitedEdges) {
  460. visitedObj.add(cps.getId());
  461. cps.resetTags();
  462. for (CpsEdge e : cps.getConnections()) {
  463. if (!(visitedEdges.contains(e))) {
  464. e.setFlow(0);
  465. e.calculateState();
  466. e.setTags(new ArrayList<>());
  467. visitedEdges.add(e);
  468. if (!(visitedObj.contains(e.getA().getId()))) {
  469. resetConnections(e.getA(), visitedObj, visitedEdges);
  470. e.getA().resetTags();
  471. }
  472. if (!(visitedObj.contains(e.getB().getId()))) {
  473. resetConnections(e.getB(), visitedObj, visitedEdges);
  474. e.getB().resetTags();
  475. }
  476. }
  477. }
  478. }
  479. /**
  480. * calculates the energy of either all producers or consumers. Flexible
  481. * devices are filtered out
  482. *
  483. * @param type
  484. * Type
  485. * @param sN
  486. * Subnet
  487. * @param x
  488. * Integer
  489. * @return The Energy
  490. */
  491. private float calculateEnergyWithoutFlexDevices(String type, SubNet sN,
  492. int x) {
  493. float energy = 0;
  494. for (HolonObject hl : sN.getObjects()) {
  495. float currentEnergyWithoutFlexibles = hl
  496. .getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(x);
  497. if (type.equals("prod")) {
  498. if (currentEnergyWithoutFlexibles > 0) {
  499. energy += currentEnergyWithoutFlexibles;
  500. hl.setState(HolonObject.PRODUCER);
  501. }
  502. }
  503. if (type.equals("cons")) {
  504. if (currentEnergyWithoutFlexibles < 0) {
  505. energy += currentEnergyWithoutFlexibles;
  506. hl.setState(HolonObject.NOT_SUPPLIED);
  507. }
  508. }
  509. if (currentEnergyWithoutFlexibles == 0) {
  510. hl.setState(HolonObject.NO_ENERGY);
  511. }
  512. }
  513. return energy;
  514. }
  515. /**
  516. * calculates the energy of either all producers or consumers. Flexible
  517. * devices are filtered out
  518. *
  519. * @param type
  520. * Type
  521. * @param sN
  522. * Subnet
  523. * @param x
  524. * Integer
  525. * @return The Energy
  526. */
  527. private float calculateEnergyWithFlexDevices(String type, SubNet sN, int x) {
  528. float energy = 0;
  529. for (HolonObject hl : sN.getObjects()) {
  530. float currentEnergy = hl.getEnergyAtTimeStep(x);
  531. if (type.equals("prod")) {
  532. if (currentEnergy > 0) {
  533. energy += currentEnergy;
  534. hl.setState(HolonObject.PRODUCER);
  535. }
  536. }
  537. if (type.equals("cons")) {
  538. if (currentEnergy < 0) {
  539. energy = energy + currentEnergy;
  540. hl.setState(HolonObject.NOT_SUPPLIED);
  541. }
  542. }
  543. if (currentEnergy == 0) {
  544. hl.setState(HolonObject.NO_ENERGY);
  545. }
  546. }
  547. return energy;
  548. }
  549. /**
  550. * Calculate the Minimum Energy of a Subnet.
  551. *
  552. * @param sN
  553. * Subnet
  554. * @param x
  555. * Integer
  556. * @return the Calculated minimum Energy of a Subnet
  557. */
  558. private float calculateMinimumEnergy(SubNet sN, int x) {
  559. float minimummConsumptionSubnet = 0;
  560. for (HolonObject hl : sN.getObjects()) {
  561. float minElement = 0;
  562. // Search for a activ element
  563. for (HolonElement he : hl.getElements()) {
  564. if (he.isActive()) {
  565. float overallEnergy = he.getOverallEnergyAtTimeStep(x);
  566. if (overallEnergy < 0) {
  567. // Is a consumer
  568. minElement = overallEnergy;
  569. }
  570. }
  571. }
  572. for (HolonElement he : hl.getElements()) {
  573. if (he.isActive()) {
  574. float overallEnergy = he.getOverallEnergyAtTimeStep(x);
  575. if (minElement < overallEnergy && overallEnergy < 0) {
  576. // is a smaller consumer
  577. minElement = overallEnergy;
  578. }
  579. }
  580. }
  581. minimummConsumptionSubnet += minElement;
  582. }
  583. System.out.println("MinimumEnergy = "+ minimummConsumptionSubnet);
  584. return minimummConsumptionSubnet;
  585. }
  586. /**
  587. * generates all subNets from all objectsToHandle.
  588. */
  589. private void searchForSubNets() {
  590. subNets = new ArrayList<>();
  591. brokenEdges.clear();
  592. boolean end = false;
  593. int i = 0;
  594. AbstractCpsObject cps;
  595. if (objectsToHandle.size() > 0) {
  596. while (!end) {
  597. cps = objectsToHandle.get(i);
  598. SubNet singleSubNet = new SubNet(new ArrayList<>(),
  599. new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
  600. singleSubNet = buildSubNet(cps, new ArrayList<>(), singleSubNet);
  601. if (singleSubNet.getObjects().size() + singleSubNet.getBatteries().size() != 0 ) {
  602. subNets.add(singleSubNet);
  603. }
  604. if (0 == objectsToHandle.size()) {
  605. end = true;
  606. }
  607. }
  608. }
  609. }
  610. /**
  611. * recursivly generates a subnet of all objects, that one specific object is
  612. * connected to.
  613. *
  614. * @param cps
  615. * AbstractCpsObject
  616. * @param visited
  617. * visited Array of Integer
  618. * @param sN
  619. * Subnets
  620. * @return Subnet
  621. */
  622. private SubNet buildSubNet(AbstractCpsObject cps,
  623. ArrayList<Integer> visited, SubNet sN) {
  624. visited.add(cps.getId());
  625. if (cps instanceof HolonObject) {
  626. sN.getObjects().add((HolonObject) cps);
  627. }
  628. if (cps instanceof HolonSwitch) {
  629. sN.getSwitches().add((HolonSwitch) cps);
  630. }
  631. if (cps instanceof HolonBattery) {
  632. sN.getBatteries().add((HolonBattery) cps);
  633. }
  634. removeFromToHandle(cps.getId());
  635. AbstractCpsObject a;
  636. AbstractCpsObject b;
  637. for (CpsEdge edge : cps.getConnections()) {
  638. if (edge.isWorking()) {
  639. a = edge.getA();
  640. b = edge.getB();
  641. if (!(cps instanceof HolonSwitch)) {
  642. if (!(sN.getEdges().contains(edge))) {
  643. sN.getEdges().add(edge);
  644. }
  645. }
  646. if (cps instanceof HolonSwitch
  647. && ((HolonSwitch) cps).getState(timeStep)) {
  648. if (!(sN.getEdges().contains(edge))) {
  649. sN.getEdges().add(edge);
  650. }
  651. }
  652. if (!visited.contains(a.getId()) && legitState(cps)
  653. && !(a instanceof CpsUpperNode)) {
  654. sN = buildSubNet(a, visited, sN);
  655. }
  656. if (!visited.contains(b.getId()) && legitState(cps)
  657. && !(b instanceof CpsUpperNode)) {
  658. sN = buildSubNet(b, visited, sN);
  659. }
  660. if (a instanceof CpsUpperNode && a.getId() != cps.getId()) {
  661. edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
  662. checkForConnectedStates(b, (CpsUpperNode) a, edge);
  663. }
  664. if (b instanceof CpsUpperNode && b.getId() != cps.getId()) {
  665. edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
  666. checkForConnectedStates(a, (CpsUpperNode) b, edge);
  667. }
  668. } else {
  669. brokenEdges.add(edge);
  670. }
  671. }
  672. return sN;
  673. }
  674. /**
  675. * is the Switch in a legitimate State.
  676. *
  677. * @param current
  678. * AbstractCpsObject
  679. * @return boolean
  680. */
  681. private boolean legitState(AbstractCpsObject current) {
  682. return !(current instanceof HolonSwitch)
  683. || ((HolonSwitch) current).getState(timeStep);
  684. }
  685. // /**
  686. // * ensures that objectsToHandle only contains HolonObjects.
  687. // */
  688. // public void cleanObjectsToHandle() {
  689. // for (int i = 0; i < objectsToHandle.size(); i++) {
  690. // if (!(objectsToHandle.get(i) instanceof HolonObject)) {
  691. // objectsToHandle.remove(i);
  692. // }
  693. // }
  694. // }
  695. /**
  696. * removes an Object that already has been handled.
  697. *
  698. * @param id
  699. * the Object ID
  700. */
  701. private void removeFromToHandle(int id) {
  702. for (int i = 0; i < objectsToHandle.size(); i++) {
  703. if (objectsToHandle.get(i).getId() == id) {
  704. objectsToHandle.remove(i);
  705. }
  706. }
  707. }
  708. /**
  709. * copies the data of an array of Objects.
  710. *
  711. * @param toCopy
  712. * the ArrayList of CpsObjects co Copy
  713. */
  714. private void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
  715. for (AbstractCpsObject cps : toCopy) {
  716. if (cps instanceof CpsUpperNode) {
  717. copyObjects(((CpsUpperNode) cps).getNodes());
  718. } else {
  719. objectsToHandle.add(cps);
  720. }
  721. }
  722. }
  723. /**
  724. * Prints the Components auf all subnets.
  725. */
  726. private void printNetsToConsole() {
  727. for (int i = 0; i < subNets.size(); i++) {
  728. SubNet subNet = subNets.get(i);
  729. System.out.println("SUBNET NR:" + i);
  730. subNet.toString(timeStep);
  731. }
  732. }
  733. /**
  734. * Set the Canvas.
  735. *
  736. * @param can
  737. * the Canvas
  738. */
  739. public void setCanvas(MyCanvas can) {
  740. canvas = can;
  741. }
  742. /**
  743. * Should be a better way to update the canvas -.-
  744. * @param can
  745. */
  746. public void updateCanvas() {
  747. canvas.repaint();
  748. }
  749. /**
  750. * Reset all Data to the current state of the Model.
  751. */
  752. public void reset() {
  753. objectsToHandle = new ArrayList<>();
  754. copyObjects(model.getObjectsOnCanvas());
  755. flexDevicesTurnedOnThisTurn = new HashMap<>();
  756. }
  757. /**
  758. * Resets the State of all Edges
  759. */
  760. private void resetEdges() {
  761. for (CpsEdge e : brokenEdges) {
  762. e.setWorkingState(true);
  763. }
  764. }
  765. /**
  766. * Resets the State for the whole Simulation Model
  767. */
  768. void resetSimulation() {
  769. reset();
  770. resetEdges();
  771. }
  772. /**
  773. * Get all Subnets.
  774. *
  775. * @return all Subnets
  776. */
  777. public ArrayList<SubNet> getSubNets() {
  778. return subNets;
  779. }
  780. /**
  781. * Get broken Edges
  782. */
  783. // public ArrayList<CpsEdge> getBrokenEdges() {
  784. // return brokenEdges;
  785. // }
  786. /**
  787. * checks whether a given object is connected to an object inside the
  788. * upperNode. if yes, the state for the edge is changed in "connected" or
  789. * "not connected"
  790. */
  791. private void checkForConnectedStates(AbstractCpsObject cps,
  792. CpsUpperNode cUNode, CpsEdge theEdge) {
  793. AbstractCpsObject tmp;
  794. for (CpsEdge edge : cps.getConnections()) {
  795. if (edge.getA().getId() == cps.getId()) {
  796. tmp = edge.getB();
  797. } else {
  798. tmp = edge.getA();
  799. }
  800. if (cUNode.getNodes().contains(tmp)) {
  801. if (tmp instanceof CpsUpperNode) {
  802. checkForConnectedStates(cps, (CpsUpperNode) tmp, theEdge);
  803. } else {
  804. theEdge.setConnected(CpsEdge.CON_UPPER_NODE_AND_INSIDE);
  805. break;
  806. }
  807. }
  808. }
  809. }
  810. public FlexiblePane getFlexiblePane() {
  811. return flexPane;
  812. }
  813. void setFlexiblePane(FlexiblePane fp) {
  814. flexPane = fp;
  815. }
  816. public DecoratedState getActualDecorStateWithOffSet(int offSet) {
  817. return getDecorState(timeStep + offSet);
  818. }
  819. public DecoratedState getActualDecorState() {
  820. return getDecorState(timeStep);
  821. }
  822. public VisualRepresentationalState getActualVisualRepresentationalState(){
  823. return savesVisual.getOrDefault(timeStep, null);
  824. }
  825. public DecoratedState getDecorState(int timestep) {
  826. return saves.getOrDefault(timestep, null);
  827. }
  828. public void setGui(GUI gui) {
  829. this.gui = gui;
  830. }
  831. public HashMap<Integer, VisualRepresentationalState> getSavesVisual() {
  832. return savesVisual;
  833. }
  834. }