SimulationManager.java 26 KB

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