SimulationManager.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. package ui.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import classes.CpsEdge;
  5. import classes.CpsNode;
  6. import classes.CpsUpperNode;
  7. import classes.AbstractCpsObject;
  8. import classes.HolonElement;
  9. import classes.HolonObject;
  10. import classes.HolonSwitch;
  11. import classes.SubNet;
  12. import ui.model.Model;
  13. import ui.view.MyCanvas;
  14. /**
  15. * Controller for Simulation.
  16. *
  17. * @author Gruppe14
  18. */
  19. public class SimulationManager {
  20. private Model model;
  21. private ArrayList<AbstractCpsObject> objectsToHandle;
  22. private ArrayList<CpsEdge> allConnections;
  23. private ArrayList<SubNet> subNets;
  24. private ArrayList<CpsEdge> brokenEdges;
  25. private MyCanvas canvas;
  26. private int timeStep;
  27. private HashMap<Integer, Float> tagTable = new HashMap<Integer, Float>();
  28. /**
  29. * Constructor.
  30. *
  31. * @param m
  32. * Model
  33. */
  34. public SimulationManager(Model m) {
  35. canvas = null;
  36. model = m;
  37. subNets = new ArrayList<SubNet>();
  38. brokenEdges = new ArrayList<CpsEdge>();
  39. }
  40. /**
  41. * calculates the flow of the edges and the supply for objects.
  42. *
  43. * @param x
  44. * current Iteration
  45. */
  46. public void calculateStateForTimeStep(int x) {
  47. reset();
  48. timeStep = x;
  49. searchForSubNets();
  50. for (SubNet singleSubNet : subNets) {
  51. resetConnections(singleSubNet.getObjects().get(0), new ArrayList<Integer>(), new ArrayList<CpsEdge>());
  52. }
  53. for (SubNet singleSubNet : subNets) {
  54. float production = calculateEnergy("prod", singleSubNet, timeStep);
  55. float consumption = calculateEnergy("cons", singleSubNet, timeStep);
  56. float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep);
  57. setFlowSimulation(singleSubNet);
  58. for (HolonObject hl : singleSubNet.getObjects()) {
  59. if (!(hl.getState() == 0) && !(hl.getState() == 3)) {
  60. for (int i = 0; i < hl.getConnections().size(); i++) {
  61. CpsEdge edge = hl.getConnectedTo().get(i);
  62. if (edge.getState() && edge.getFlow() > 0 || edge.getCapacity() == -1) {
  63. // 0 = no energy, 1 = not supplied, 2 = supplied, 3
  64. // = producer, 4 = partially supplied
  65. if ((production + consumption) >= 0) {
  66. hl.setState(2);
  67. }
  68. if ((production + consumption) < 0) {
  69. if ((production + minConsumption) >= 0) {
  70. hl.setState(4);
  71. } else if (hl.checkIfPartiallySupplied(timeStep)) {
  72. hl.setState(4);
  73. } else {
  74. hl.setState(1);
  75. }
  76. }
  77. break;
  78. }
  79. hl.setState(1);
  80. }
  81. if (hl.checkIfPartiallySupplied(timeStep) && !(hl.getState() == 2)) {
  82. hl.setState(4);
  83. }
  84. }
  85. }
  86. }
  87. canvas.repaint();
  88. //printNet();
  89. }
  90. /**
  91. * Set Flow Simulation.
  92. *
  93. * @param sN
  94. * Subnet
  95. */
  96. public void setFlowSimulation(SubNet sN) {
  97. ArrayList<AbstractCpsObject> producers = new ArrayList<AbstractCpsObject>();
  98. AbstractCpsObject tmp = null;
  99. tagTable = new HashMap<Integer, Float>();
  100. for (HolonObject hl : sN.getObjects()) {
  101. float energy = hl.getCurrentEnergyAtTimeStep(timeStep);
  102. if (energy > 0) {
  103. tagTable.put(hl.getId(), energy);
  104. hl.addTag(hl.getId());
  105. for (CpsEdge edge : hl.getConnections()) {
  106. if (edge.getState()) {
  107. if (edge.getA().getId() == hl.getId()) {
  108. edge.getB().addTag(hl.getId());
  109. tmp = edge.getB();
  110. }
  111. if (edge.getB().getId() == hl.getId()) {
  112. edge.getA().addTag(hl.getId());
  113. tmp = edge.getA();
  114. }
  115. edge.setFlow(edge.getFlow() + energy);
  116. edge.calculateState();
  117. edge.addTag(hl.getId());
  118. if (edge.getState() && !producers.contains(tmp)) {
  119. if(tmp instanceof HolonSwitch){
  120. if(((HolonSwitch)tmp).getState(timeStep)){
  121. producers.add(tmp);
  122. }
  123. }else if(!(tmp instanceof CpsUpperNode)){
  124. producers.add(tmp);
  125. }
  126. }
  127. }
  128. }
  129. }
  130. }
  131. setFlowSimRec(producers, 0);
  132. }
  133. /**
  134. * Set Flow Rimulation Rec.
  135. *
  136. * @param nodes
  137. * the nodes
  138. * @param iter
  139. * the Iteration
  140. */
  141. public void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
  142. ArrayList<AbstractCpsObject> newNodes = new ArrayList<AbstractCpsObject>();
  143. ArrayList<CpsEdge> changedEdges = new ArrayList<CpsEdge>();
  144. AbstractCpsObject tmp;
  145. if(nodes.size() != 0){
  146. for(AbstractCpsObject cps: nodes){
  147. if(legitState(cps)){
  148. for(CpsEdge edge: cps.getConnections()){
  149. if(edge.getState() && (!(edge.containsTags(edge.getTags(), cps.getTag())))){
  150. if(edge.getA().getId() == cps.getId()){
  151. tmp = edge.getB();
  152. }else{
  153. tmp = edge.getA();
  154. }
  155. for(Integer tag: cps.getTag()){
  156. if(!(edge.getTags().contains(tag)) && !(edge.getPseudoTags().contains(tag))){
  157. edge.setFlow(edge.getFlow() + tagTable.get(tag));
  158. edge.addTag(tag);
  159. }
  160. }
  161. // uppernodes do not spread energy
  162. if(!(tmp instanceof CpsUpperNode)){
  163. for(Integer tag: tmp.getTag()){
  164. if(!(edge.getTags().contains(tag)) && tagTable.get(tag) != null && !(edge.getPseudoTags().contains(tag))){
  165. edge.setFlow(edge.getFlow() + tagTable.get(tag));
  166. edge.addPseudoTag(tag);
  167. changedEdges.add(edge);
  168. }
  169. }
  170. }
  171. edge.calculateState();
  172. if(edge.getState() && !(tmp instanceof CpsUpperNode)){
  173. tmp.addAllPseudoTags(cps.getTag());
  174. if(!newNodes.contains(tmp)){
  175. newNodes.add(tmp);
  176. }
  177. }
  178. }
  179. }
  180. }
  181. }
  182. setPseudoTags(newNodes, changedEdges);
  183. setFlowSimRec(newNodes, iter+1);
  184. }
  185. }
  186. /**
  187. * Set the Pseudo Tags.
  188. *
  189. * @param nodes
  190. * Array of AbstractCpsObjects
  191. */
  192. public void setPseudoTags(ArrayList<AbstractCpsObject> nodes, ArrayList<CpsEdge> edges) {
  193. for (AbstractCpsObject node : nodes) {
  194. node.recalculateTags();
  195. node.setPseudoTags(new ArrayList<Integer>());
  196. }
  197. for(CpsEdge edge : edges){
  198. edge.recalculateTags();
  199. edge.setPseudoTag(new ArrayList<Integer>());
  200. }
  201. }
  202. /**
  203. * Print the nodes.
  204. *
  205. * @param nodes
  206. * Array of AbstractCpsObject
  207. */
  208. public void printNodes(ArrayList<AbstractCpsObject> nodes) {
  209. System.out.println("new Nodes:");
  210. for (AbstractCpsObject node : nodes) {
  211. System.out.println(node.getId());
  212. }
  213. }
  214. /**
  215. * Get String.
  216. *
  217. * @param tags
  218. * the tags
  219. * @return the String
  220. */
  221. public String getString(ArrayList<Integer> tags) {
  222. String result = "";
  223. for (Integer i : tags) {
  224. result = result + ", " + i;
  225. }
  226. return result;
  227. }
  228. /**
  229. * Merge the Lists.
  230. *
  231. * @param a
  232. * first liust
  233. * @param b
  234. * second list
  235. * @return the Result
  236. */
  237. public ArrayList<Integer> mergeLists(ArrayList<Integer> a, ArrayList<Integer> b) {
  238. ArrayList<Integer> result = new ArrayList<Integer>();
  239. for (Integer i : a) {
  240. if (!(result.contains(i))) {
  241. result.add(i);
  242. }
  243. }
  244. for (Integer j : b) {
  245. if (!(result.contains(j))) {
  246. result.add(j);
  247. }
  248. }
  249. return result;
  250. }
  251. /**
  252. * Reset the Connection.
  253. *
  254. * @param cps
  255. * CpsObject
  256. * @param visitedObj
  257. * the visited Objects
  258. * @param visitedEdges
  259. * the visited Edges
  260. */
  261. public void resetConnections(AbstractCpsObject cps, ArrayList<Integer> visitedObj,
  262. ArrayList<CpsEdge> visitedEdges) {
  263. visitedObj.add(cps.getId());
  264. cps.resetTags();
  265. for (CpsEdge e : cps.getConnections()) {
  266. if (!(visitedEdges.contains(e))) {
  267. e.setFlow(0);
  268. e.calculateState();
  269. e.setTags(new ArrayList<Integer>());
  270. visitedEdges.add(e);
  271. if (!(visitedObj.contains(e.getA().getId()))) {
  272. resetConnections(e.getA(), visitedObj, visitedEdges);
  273. e.getA().resetTags();
  274. }
  275. if (!(visitedObj.contains(e.getB().getId()))) {
  276. resetConnections(e.getB(), visitedObj, visitedEdges);
  277. e.getB().resetTags();
  278. }
  279. }
  280. }
  281. }
  282. /**
  283. * calculates the energy of either all producers or consumers.
  284. *
  285. * @param type
  286. * Type
  287. * @param sN
  288. * Subnet
  289. * @param x
  290. * Integer
  291. *
  292. * @return The Energy
  293. */
  294. public float calculateEnergy(String type, SubNet sN, int x) {
  295. float energy = 0;
  296. for (HolonObject hl : sN.getObjects()) {
  297. if (type.equals("prod")) {
  298. if (hl.getCurrentEnergyAtTimeStep(x) > 0) {
  299. energy = energy + hl.getCurrentEnergyAtTimeStep(x);
  300. hl.setState(3);
  301. }
  302. }
  303. if (type.equals("cons")) {
  304. if (hl.getCurrentEnergyAtTimeStep(x) < 0) {
  305. energy = energy + hl.getCurrentEnergyAtTimeStep(x);
  306. hl.setState(1);
  307. }
  308. }
  309. if (hl.getCurrentEnergyAtTimeStep(x) == 0) {
  310. hl.setState(0);
  311. }
  312. }
  313. return energy;
  314. }
  315. /**
  316. * Calculate the Minimum Energy.
  317. *
  318. * @param sN
  319. * Subnet
  320. * @param x
  321. * Integer
  322. * @return the Calculated minimum Energy
  323. */
  324. public float calculateMinimumEnergy(SubNet sN, int x) {
  325. float min = 0;
  326. float minElement = 0;
  327. for (HolonObject hl : sN.getObjects()) {
  328. if (hl.getElements().size() > 0 && hl.getElements().get(0).getTotalEnergyAtTimeStep(x) < 0) {
  329. minElement = hl.getElements().get(0).getTotalEnergyAtTimeStep(x);
  330. }
  331. for (HolonElement he : hl.getElements()) {
  332. if (minElement < he.getTotalEnergyAtTimeStep(x) && he.getTotalEnergyAtTimeStep(x) < 0) {
  333. minElement = he.getTotalEnergyAtTimeStep(x);
  334. }
  335. }
  336. min = min + minElement;
  337. }
  338. return min;
  339. }
  340. /**
  341. * generates all subNets from all objectsToHandle.
  342. */
  343. public void searchForSubNets() {
  344. subNets = new ArrayList<SubNet>();
  345. brokenEdges.clear();
  346. boolean end = false;
  347. int i = 0;
  348. AbstractCpsObject cps;
  349. if (objectsToHandle.size() > 0) {
  350. while (!end) {
  351. cps = objectsToHandle.get(i);
  352. SubNet singleSubNet = new SubNet(new ArrayList<HolonObject>(), new ArrayList<CpsEdge>(),
  353. new ArrayList<HolonSwitch>());
  354. singleSubNet = buildSubNet(cps, new ArrayList<Integer>(), singleSubNet);
  355. if (singleSubNet.getObjects().size() != 0) {
  356. subNets.add(singleSubNet);
  357. }
  358. if (0 == objectsToHandle.size()) {
  359. end = true;
  360. }
  361. }
  362. }
  363. }
  364. /**
  365. * recursivly generates a subnet of all objects, that one specific object is
  366. * connected to.
  367. *
  368. * @param cps
  369. * AbstractCpsObject
  370. * @param visited
  371. * visited Array of Integer
  372. * @param sN
  373. * Subnets
  374. * @return Subnet
  375. */
  376. public SubNet buildSubNet(AbstractCpsObject cps, ArrayList<Integer> visited, SubNet sN) {
  377. visited.add(cps.getId());
  378. if (cps instanceof HolonObject) {
  379. sN.getObjects().add((HolonObject) cps);
  380. }
  381. if (cps instanceof HolonSwitch) {
  382. sN.getSwitches().add((HolonSwitch) cps);
  383. }
  384. removeFromToHandle(cps.getId());
  385. AbstractCpsObject a;
  386. AbstractCpsObject b;
  387. for (CpsEdge edge : cps.getConnections()) {
  388. if(edge.getState()){
  389. a = edge.getA();
  390. b = edge.getB();
  391. if (!(cps instanceof HolonSwitch)) {
  392. if (!(sN.getEdges().contains(edge))) {
  393. sN.getEdges().add(edge);
  394. }
  395. }
  396. if(cps instanceof HolonSwitch && ((HolonSwitch)cps).getState(timeStep)){
  397. if (!(sN.getEdges().contains(edge))) {
  398. sN.getEdges().add(edge);
  399. }
  400. }
  401. if (!visited.contains(a.getId()) && legitState(cps) && !(a instanceof CpsUpperNode)) {
  402. sN = buildSubNet(a, visited, sN);
  403. }
  404. if (!visited.contains(b.getId()) && legitState(cps) && !(b instanceof CpsUpperNode)) {
  405. sN = buildSubNet(b, visited, sN);
  406. }
  407. if(a instanceof CpsUpperNode && a.getId() != cps.getId()){
  408. edge.setConnected(2);
  409. checkForConnectedStates(b, (CpsUpperNode)a, edge);
  410. }
  411. if(b instanceof CpsUpperNode && b.getId() != cps.getId()){
  412. edge.setConnected(2);
  413. checkForConnectedStates(a, (CpsUpperNode)b, edge);
  414. }
  415. }else{
  416. brokenEdges.add(edge);
  417. }
  418. }
  419. return sN;
  420. }
  421. /**
  422. * is the Switch in a legitimate State.
  423. *
  424. * @param neighbor AbstractCpsObject
  425. * @param current AbstractCpsObject
  426. * @return boolean
  427. */
  428. public boolean legitState(AbstractCpsObject current) {
  429. if (current instanceof HolonSwitch) {
  430. if (((HolonSwitch) current).getState(timeStep)) {
  431. return true;
  432. }else{
  433. return false;
  434. }
  435. }
  436. return true;
  437. }
  438. /**
  439. * removes an Object that already has been handled with.
  440. *
  441. * @param id the Object ID
  442. */
  443. public void removeFromToHandle(int id) {
  444. for (int i = 0; i < objectsToHandle.size(); i++) {
  445. if (objectsToHandle.get(i).getId() == id) {
  446. objectsToHandle.remove(i);
  447. }
  448. }
  449. }
  450. /**
  451. * ensures that objectsToHandle only contains HolonObjects.
  452. */
  453. public void cleanObjectsToHandle() {
  454. for (int i = 0; i < objectsToHandle.size(); i++) {
  455. if (!(objectsToHandle.get(i) instanceof HolonObject)) {
  456. objectsToHandle.remove(i);
  457. }
  458. }
  459. }
  460. /**
  461. * copies the data of an array of Objects.
  462. *
  463. * @param toCopy the ArrayList of CpsObjects co Copy
  464. */
  465. public void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
  466. for (AbstractCpsObject cps : toCopy) {
  467. if(cps instanceof CpsUpperNode){
  468. copyObjects(((CpsUpperNode)cps).getNodes());
  469. }else{
  470. objectsToHandle.add(cps);
  471. }
  472. }
  473. }
  474. /**
  475. * Prints the Components auf all subnets.
  476. */
  477. public void printNet() {
  478. for (int i = 0; i < subNets.size(); i++) {
  479. System.out.println("SUBNET NR:" + i);
  480. System.out.println(" Objects:");
  481. for (int j = 0; j < subNets.get(i).getObjects().size(); j++) {
  482. HolonObject hl = subNets.get(i).getObjects().get(j);
  483. System.out.println(" " + hl.getName() + " " + hl.getId());
  484. }
  485. System.out.println(" Edges:");
  486. for (int j = 0; j < subNets.get(i).getEdges().size(); j++) {
  487. CpsEdge edge = subNets.get(i).getEdges().get(j);
  488. System.out.println(" " + edge.getA().getName() + " connected To " + edge.getB().getName());
  489. }
  490. System.out.println(" Switches:");
  491. for (int j = 0; j < subNets.get(i).getSwitches().size(); j++) {
  492. HolonSwitch sw = subNets.get(i).getSwitches().get(j);
  493. System.out.println(" " + sw.getName() + " " + sw.getId() + " State:" + sw.getActiveAt()[timeStep]);
  494. }
  495. }
  496. }
  497. /**
  498. * Set the Canvas.
  499. *
  500. * @param can
  501. * the Canvas
  502. */
  503. public void setCanvas(MyCanvas can) {
  504. canvas = can;
  505. }
  506. /**
  507. * Reset all Data to the current state of the Model.
  508. */
  509. public void reset() {
  510. objectsToHandle = new ArrayList<AbstractCpsObject>();
  511. copyObjects(model.getObjectsOnCanvas());
  512. }
  513. /**
  514. * Resets the State of all Edges
  515. */
  516. public void resetEdges(){
  517. for(CpsEdge e: brokenEdges){
  518. e.setState(true);
  519. }
  520. }
  521. /**
  522. * Resets the State for the whole Simulation Model
  523. */
  524. public void resetSimulation(){
  525. reset();
  526. resetEdges();
  527. }
  528. /**
  529. * Get all Subnets.
  530. *
  531. * @return all Subnets
  532. */
  533. public ArrayList<SubNet> getSubNets() {
  534. return subNets;
  535. }
  536. /**
  537. * Get broken Edges
  538. */
  539. public ArrayList<CpsEdge> getBrokenEdges(){
  540. return brokenEdges;
  541. }
  542. /**
  543. * checks wether a given object is connected to an object inside the upperNode.
  544. * if yes, the state for the edge is changed in "connected" or "not connected"
  545. * @param cps
  546. * @param cUNode
  547. */
  548. public void checkForConnectedStates(AbstractCpsObject cps, CpsUpperNode cUNode, CpsEdge theEdge){
  549. AbstractCpsObject tmp;
  550. for(CpsEdge edge: cps.getConnections()){
  551. if(edge.getA().getId() == cps.getId()){
  552. tmp = edge.getB();
  553. } else{
  554. tmp = edge.getA();
  555. }
  556. if(cUNode.getNodes().contains(tmp)){
  557. if(tmp instanceof CpsUpperNode){
  558. checkForConnectedStates(cps, (CpsUpperNode)tmp, theEdge);
  559. }else{
  560. theEdge.setConnected(1);
  561. break;
  562. }
  563. }
  564. }
  565. }
  566. }