AcoAlgorithm.java 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. package exampleAlgorithms;
  2. import java.awt.BorderLayout;
  3. import java.awt.Component;
  4. import java.awt.Dimension;
  5. import java.awt.FlowLayout;
  6. import java.awt.image.BufferedImage;
  7. import java.io.BufferedWriter;
  8. import java.io.File;
  9. import java.io.FileOutputStream;
  10. import java.io.IOException;
  11. import java.io.OutputStreamWriter;
  12. import java.math.RoundingMode;
  13. import java.text.NumberFormat;
  14. import java.util.ArrayList;
  15. import java.util.HashMap;
  16. import java.util.LinkedList;
  17. import java.util.List;
  18. import java.util.ListIterator;
  19. import java.util.Locale;
  20. import java.util.stream.Collectors;
  21. import javax.swing.BorderFactory;
  22. import javax.swing.ImageIcon;
  23. import javax.swing.JButton;
  24. import javax.swing.JCheckBox;
  25. import javax.swing.JFileChooser;
  26. import javax.swing.JFormattedTextField;
  27. import javax.swing.JFrame;
  28. import javax.swing.JLabel;
  29. import javax.swing.JOptionPane;
  30. import javax.swing.JPanel;
  31. import javax.swing.JProgressBar;
  32. import javax.swing.JScrollPane;
  33. import javax.swing.JSplitPane;
  34. import javax.swing.JTextArea;
  35. import javax.swing.text.NumberFormatter;
  36. import api.AddOn;
  37. import classes.AbstractCpsObject;
  38. import classes.CpsUpperNode;
  39. import classes.HolonElement;
  40. import classes.HolonObject;
  41. import classes.HolonSwitch;
  42. import exampleAlgorithms.GaAlgorithm.RunDataBase;
  43. import ui.controller.Control;
  44. import ui.model.DecoratedGroupNode;
  45. import ui.model.DecoratedState;
  46. import ui.model.Model;
  47. import ui.view.Console;
  48. import ui.model.DecoratedHolonObject.HolonObjectState;
  49. public class AcoAlgorithm implements AddOn {
  50. //Parameter for Algo with default Values:
  51. /**
  52. * Should be even.
  53. */
  54. private int popsize = 20;
  55. private int maxGenerations = 200;
  56. /**
  57. * The vaporization factor;
  58. */
  59. private double p = 0.3;
  60. private double convergenceFactorReset = 0.99;
  61. private int rounds = 3;
  62. private int resetCount = 0;
  63. private boolean moreInformation = false;
  64. //Settings For GroupNode using and cancel
  65. private boolean useGroupNode = false;
  66. private DecoratedGroupNode dGroupNode = null;
  67. private boolean cancel = false;
  68. //Parameter defined by Algo
  69. private HashMap<Integer, AccessWrapper> access;
  70. LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
  71. private List<HolonSwitch> switchList;
  72. private List<HolonObject> objectList;
  73. private boolean append = false;
  74. //Gui Part:
  75. private Control control;
  76. private Console console = new Console();
  77. private JPanel content = new JPanel();
  78. //ProgressBar
  79. private JProgressBar progressBar = new JProgressBar();
  80. private int progressBarCount = 0;
  81. private long startTime;
  82. private Thread runThread = new Thread();
  83. private RunDataBase db;
  84. //Parameter for Plotting (Default Directory in Constructor)
  85. private JFileChooser fileChooser = new JFileChooser();
  86. public static void main(String[] args)
  87. {
  88. JFrame newFrame = new JFrame("exampleWindow");
  89. AcoAlgorithm instance = new AcoAlgorithm();
  90. newFrame.setContentPane(instance.getPanel());
  91. newFrame.pack();
  92. newFrame.setVisible(true);
  93. newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  94. }
  95. public AcoAlgorithm() {
  96. content.setLayout(new BorderLayout());
  97. JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
  98. createOptionPanel() , console);
  99. splitPane.setResizeWeight(0.0);
  100. content.add(splitPane, BorderLayout.CENTER);
  101. content.setPreferredSize(new Dimension(800,800));
  102. fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
  103. fileChooser.setSelectedFile(new File("plott.txt"));
  104. }
  105. public JPanel createOptionPanel() {
  106. JPanel optionPanel = new JPanel(new BorderLayout());
  107. JScrollPane scrollPane = new JScrollPane(createParameterPanel());
  108. scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter"));
  109. optionPanel.add(scrollPane, BorderLayout.CENTER);
  110. optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
  111. return optionPanel;
  112. }
  113. private Component createParameterPanel() {
  114. JPanel parameterPanel = new JPanel(null);
  115. parameterPanel.setPreferredSize(new Dimension(510,300));
  116. JLabel maxGenerationsLabel = new JLabel("Max. Generations:");
  117. maxGenerationsLabel.setBounds(20, 60, 150, 20);
  118. parameterPanel.add(maxGenerationsLabel);
  119. JLabel populationLabel = new JLabel("Population Size:");
  120. populationLabel.setBounds(20, 85, 150, 20);
  121. parameterPanel.add(populationLabel);
  122. JLabel roundLabel = new JLabel("Rounds:");
  123. roundLabel.setBounds(20, 110, 150, 20);
  124. parameterPanel.add(roundLabel);
  125. JLabel vaporizationLabel = new JLabel("Vaporization:");
  126. vaporizationLabel.setBounds(20, 135, 150, 20);
  127. parameterPanel.add(vaporizationLabel);
  128. JLabel resetLabel = new JLabel("Reset Trigger:");
  129. resetLabel.setBounds(20, 160, 150, 20);
  130. parameterPanel.add(resetLabel);
  131. JLabel progressLabel = new JLabel("Progress:");
  132. progressLabel.setBounds(350, 135, 170, 20);
  133. parameterPanel.add(progressLabel);
  134. progressBar.setBounds(350, 155, 185, 20);
  135. progressBar.setStringPainted(true);
  136. parameterPanel.add(progressBar);
  137. JCheckBox informationCheckBox = new JCheckBox("More Information");
  138. informationCheckBox.setSelected(this.moreInformation);
  139. informationCheckBox.setBounds(350, 60, 220, 20);
  140. informationCheckBox.addActionListener(actionEvent -> {
  141. moreInformation = informationCheckBox.isSelected();
  142. });
  143. parameterPanel.add(informationCheckBox);
  144. JPanel borderPanel = new JPanel(null);
  145. borderPanel.setBounds(350, 85, 185, 50);
  146. borderPanel.setBorder(BorderFactory.createTitledBorder(""));
  147. parameterPanel.add(borderPanel);
  148. JLabel showGroupNodeLabel = new JLabel("Use Group Node:");
  149. showGroupNodeLabel.setBounds(10, 1, 170, 20);
  150. borderPanel.add(showGroupNodeLabel);
  151. JButton selectGroupNodeButton = new JButton("Select GroupNode");
  152. selectGroupNodeButton.setEnabled(false);
  153. selectGroupNodeButton.setBounds(10, 25, 165, 20);
  154. selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode());
  155. borderPanel.add(selectGroupNodeButton);
  156. JCheckBox useGroupNodeCheckBox = new JCheckBox();
  157. useGroupNodeCheckBox.setSelected(false);
  158. useGroupNodeCheckBox.setBounds(155, 1, 25, 20);
  159. useGroupNodeCheckBox.addActionListener(actionEvent -> {
  160. useGroupNode = useGroupNodeCheckBox.isSelected();
  161. selectGroupNodeButton.setEnabled(useGroupNode);
  162. });
  163. borderPanel.add(useGroupNodeCheckBox);
  164. //Integer formatter
  165. NumberFormat format = NumberFormat.getIntegerInstance();
  166. format.setGroupingUsed(false);
  167. format.setParseIntegerOnly(true);
  168. NumberFormatter integerFormatter = new NumberFormatter(format);
  169. integerFormatter.setMinimum(1);
  170. integerFormatter.setCommitsOnValidEdit(true);
  171. JFormattedTextField maxGenerationsTextField = new JFormattedTextField(integerFormatter);
  172. maxGenerationsTextField.setValue(this.maxGenerations);
  173. maxGenerationsTextField.setToolTipText("Only positive Integer.");
  174. maxGenerationsTextField.addPropertyChangeListener(actionEvent -> this.maxGenerations = Integer.parseInt(maxGenerationsTextField.getValue().toString()));
  175. maxGenerationsTextField.setBounds(160, 60, 50, 20);
  176. parameterPanel.add(maxGenerationsTextField);
  177. JFormattedTextField popSizeTextField = new JFormattedTextField(integerFormatter);
  178. popSizeTextField.setValue(this.popsize);
  179. popSizeTextField.setToolTipText("Only positive Integer.");
  180. popSizeTextField.addPropertyChangeListener(propertyChange -> this.popsize = Integer.parseInt(popSizeTextField.getValue().toString()));
  181. popSizeTextField.setBounds(160, 85, 50, 20);
  182. parameterPanel.add(popSizeTextField);
  183. JFormattedTextField roundsTextField = new JFormattedTextField(integerFormatter);
  184. roundsTextField.setValue(this.rounds);
  185. roundsTextField.setToolTipText("Only positive Integer.");
  186. roundsTextField.addPropertyChangeListener(propertyChange -> this.rounds = Integer.parseInt(roundsTextField.getValue().toString()));
  187. roundsTextField.setBounds(160, 110, 50, 20);
  188. parameterPanel.add(roundsTextField);
  189. //Double Format:
  190. NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
  191. doubleFormat.setMinimumFractionDigits(1);
  192. doubleFormat.setMaximumFractionDigits(3);
  193. doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
  194. //Limit Formatter:
  195. NumberFormatter limitFormatter = new NumberFormatter(doubleFormat);
  196. limitFormatter.setMinimum(0.0);
  197. limitFormatter.setMaximum(1.0);
  198. JFormattedTextField vaporizationField = new JFormattedTextField(limitFormatter);
  199. vaporizationField.setValue(this.p);
  200. vaporizationField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
  201. vaporizationField.addPropertyChangeListener(propertyChange -> p = Double.parseDouble(vaporizationField.getValue().toString()));
  202. vaporizationField.setBounds(160, 135, 50, 20);
  203. parameterPanel.add(vaporizationField);
  204. JFormattedTextField resetFactorField = new JFormattedTextField(limitFormatter);
  205. resetFactorField.setValue(this.convergenceFactorReset);
  206. resetFactorField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
  207. resetFactorField.addPropertyChangeListener(propertyChange -> this.convergenceFactorReset = Double.parseDouble(resetFactorField.getValue().toString()));
  208. resetFactorField.setBounds(160, 160, 50, 20);
  209. parameterPanel.add(resetFactorField);
  210. return parameterPanel;
  211. }
  212. public JPanel createButtonPanel() {
  213. JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  214. JButton fitnessButton = new JButton("Fitness");
  215. fitnessButton.setToolTipText("Fitness for the current state.");
  216. fitnessButton.addActionListener(actionEvent -> fitness());
  217. buttonPanel.add(fitnessButton);
  218. JButton plottButton = new JButton("Plott");
  219. plottButton.addActionListener(actionEvent -> plott());
  220. buttonPanel.add(plottButton);
  221. JButton resetButton = new JButton("ResetAll");
  222. resetButton.setToolTipText("Resets the State to before the Algorithm has runed.");
  223. resetButton.addActionListener(actionEvent -> resetAll());
  224. buttonPanel.add(resetButton);
  225. JButton cancelButton = new JButton("Cancel Run");
  226. cancelButton.addActionListener(actionEvent -> cancel());
  227. buttonPanel.add(cancelButton);
  228. JButton undoButton = new JButton("Undo");
  229. undoButton.setToolTipText("One Algo Step Back.");
  230. undoButton.addActionListener(actionEvent -> resetLast());
  231. buttonPanel.add(undoButton);
  232. JButton runButton = new JButton("Run");
  233. runButton.addActionListener(actionEvent -> {
  234. Runnable task = () -> run();
  235. runThread = new Thread(task);
  236. runThread.start();
  237. });
  238. buttonPanel.add(runButton);
  239. return buttonPanel;
  240. }
  241. private void cancel() {
  242. if(runThread.isAlive()) {
  243. println("");
  244. println("Cancel run.");
  245. cancel = true;
  246. progressBar.setValue(0);
  247. } else {
  248. println("Nothing to cancel.");
  249. }
  250. }
  251. private void fitness() {
  252. if(runThread.isAlive()) {
  253. println("Run have to be cancelled First.");
  254. return;
  255. }
  256. double currentFitness = evaluatePosition(extractPositionAndAccess(), false);
  257. resetChain.removeLast();
  258. console.println("Actual Fitnessvalue: " + currentFitness);
  259. }
  260. private void run() {
  261. cancel = false;
  262. disableGuiInput(true);
  263. executeAlgoWithParameter();
  264. updateVisual();
  265. disableGuiInput(false);
  266. }
  267. private void resetLast() {
  268. if(runThread.isAlive()) {
  269. println("Run have to be cancelled First.");
  270. return;
  271. }
  272. if(!resetChain.isEmpty()) {
  273. println("Resetting..");
  274. resetState();
  275. resetChain.removeLast();
  276. control.resetSimulation();
  277. updateVisual();
  278. }else {
  279. println("No run inistialized.");
  280. }
  281. }
  282. private void resetAll() {
  283. if(runThread.isAlive()) {
  284. println("Run have to be cancelled First.");
  285. return;
  286. }
  287. if(!resetChain.isEmpty()) {
  288. println("Resetting..");
  289. setState(resetChain.getFirst());
  290. resetChain.clear();
  291. control.resetSimulation();
  292. control.setCurIteration(0);
  293. updateVisual();
  294. }else {
  295. println("No run inistialized.");
  296. }
  297. }
  298. private void plott() {
  299. if(db!=null) {
  300. console.println("Plott..");
  301. db.initFileStream();
  302. }else {
  303. console.println("No run inistialized.");
  304. }
  305. }
  306. private void disableGuiInput(boolean bool) {
  307. control.guiDisable(bool);
  308. }
  309. @Override
  310. public JPanel getPanel() {
  311. return content;
  312. }
  313. @Override
  314. public void setController(Control control) {
  315. this.control = control;
  316. }
  317. private void println(String message) {
  318. console.println(message);
  319. }
  320. private void selectGroupNode() {
  321. Object[] possibilities = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().values().stream().map(aCps -> new Handle<DecoratedGroupNode>(aCps)).toArray();
  322. @SuppressWarnings("unchecked")
  323. Handle<DecoratedGroupNode> selected = (Handle<DecoratedGroupNode>) JOptionPane.showInputDialog(content, "Select GroupNode:", "GroupNode?", JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , possibilities, "");
  324. if(selected != null) {
  325. println("Selected: " + selected);
  326. dGroupNode = selected.object;
  327. }
  328. }
  329. private void progressBarStep(){
  330. progressBar.setValue(++progressBarCount);
  331. }
  332. private void calculateProgressBarParameter() {
  333. int max = this.maxGenerations * this.popsize * this.rounds;
  334. progressBarCount = 0;
  335. progressBar.setValue(0);
  336. progressBar.setMaximum(max);
  337. }
  338. private void startTimer(){
  339. startTime = System.currentTimeMillis();
  340. }
  341. private void printElapsedTime(){
  342. long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
  343. println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds);
  344. }
  345. private void executeAlgoWithParameter(){
  346. int actualIteration = control.getModel().getCurIteration();
  347. println("TimeStep:" + actualIteration);
  348. calculateProgressBarParameter();
  349. println("Algo Parameter: p="+ p + " cfreset=" + convergenceFactorReset);
  350. resetCount = 0;
  351. startTimer();
  352. Individual runBest = new Individual();
  353. runBest.fitness = Double.MAX_VALUE;
  354. db = new RunDataBase();
  355. for(int r = 0; r < rounds; r++)
  356. {
  357. List<Double> runList = db.insertNewRun();
  358. Individual roundBest = executeAcoAlgo(runList);
  359. if(cancel)return;
  360. resetState();
  361. if(roundBest.fitness < runBest.fitness) runBest = roundBest;
  362. }
  363. printElapsedTime();
  364. setState(runBest.position);
  365. updateVisual();
  366. if(moreInformation)println("ResetsCount:"+resetCount);
  367. println("AlgoResult:" + runBest.fitness);
  368. }
  369. //Algo Part:
  370. /**
  371. * Algorithm 20 !! Fitness is better when smaller.:
  372. * PseudoCode:
  373. * Best <- actual;
  374. * pheromones = initPheromons();
  375. * for(maxGeneration times){
  376. * population = createSolutionsBiasedBy(pheromones);
  377. * for(each Individual i from population){
  378. * fitness <- evaluatePosition(i);
  379. * if(fitness < best.fitnessValue) Best <- i;
  380. * }
  381. * vaporizeIntensifiePheromons(pheromones);
  382. * }
  383. * @return
  384. */
  385. private Individual executeAcoAlgo(List<Double> runList) {
  386. Individual best = new Individual();
  387. best.position = extractPositionAndAccess();
  388. if(moreInformation)println("Bit-Array_length: " + best.position.size());
  389. best.fitness = evaluatePosition(best.position, false);
  390. runList.add(best.fitness);
  391. console.print("Start with: " + best.fitness);
  392. if(moreInformation)println("");
  393. int problemSize = best.position.size();
  394. if(problemSize == 0) return best;
  395. List<Double> pheromones = initPheromones(problemSize);
  396. List<Individual> population = new ArrayList<Individual>();
  397. if(moreInformation)println("Size To Test:" + population.size());
  398. for(int generation = 0; generation< maxGenerations; generation++) {
  399. population.clear();
  400. population = constructSolutionsBiasedBy(pheromones);
  401. if(moreInformation)println("Generation" + generation + " start with Fitness: " + best.fitness);
  402. for(Individual i : population) {
  403. i.fitness = evaluatePosition(i.position, true);
  404. if(moreInformation)println("Fitness" + i.fitness);
  405. if(i.fitness < best.fitness) best = i;
  406. }
  407. runList.add(best.fitness);
  408. if(moreInformation)println("________________");
  409. vaporizeIntensifiePheromons(pheromones, best.position, problemSize);
  410. double cf = calculateConvergenceFactor(pheromones, problemSize);
  411. if(moreInformation)println("ConvergenceFactor = " + cf);
  412. if(cf > this.convergenceFactorReset) {
  413. pheromones = initPheromones(problemSize);
  414. resetCount++;
  415. }
  416. if(cancel)return null;
  417. }
  418. println(" End With:" + best.fitness);
  419. return best;
  420. }
  421. /**
  422. * tj1 is the pheromon level in the j position
  423. * cf is the convergence factor cf e [0;1]
  424. * difference = | tj1 - tj0 | = | tj1 - (1 - tj1) |
  425. *
  426. *
  427. *
  428. * @param pheromones
  429. * @return cf
  430. */
  431. private double calculateConvergenceFactor(List<Double> pheromones,int problemSize) {
  432. double sumOfDifference = pheromones.stream().map(tj1 -> Math.abs(tj1 - (1.0 - tj1))).reduce(0.0, Double::sum);
  433. double cf = sumOfDifference / (double)problemSize;
  434. return cf;
  435. }
  436. /**
  437. * pheromone <- (1-p) * pheromone;
  438. * if(best is true at this position) pheromone <- pheromone + p;
  439. * @param pheromones
  440. * @param position
  441. */
  442. private void vaporizeIntensifiePheromons(List<Double> pheromones, List<Boolean> position, int problemSize) {
  443. ListIterator<Double> iterPheromone = pheromones.listIterator();
  444. ListIterator<Boolean> iterBest = position.listIterator();
  445. for(int i = 0; i < problemSize; i++) {
  446. double pheromone = iterPheromone.next();
  447. boolean bestDecision = iterBest.next();
  448. iterPheromone.set((1.0 - p) * pheromone + (bestDecision?p:0.0));
  449. }
  450. }
  451. /**
  452. *
  453. * @param pheromones
  454. * @return
  455. */
  456. private List<Individual> constructSolutionsBiasedBy(List<Double> pheromones) {
  457. List<Individual> population = new ArrayList<Individual>();
  458. for(int i = 0; i < popsize; i++) {
  459. population.add(constructASolutionBiasedBy(pheromones));
  460. }
  461. return population;
  462. }
  463. /**
  464. * Walks the path with a ant and decide by pheromones if should take true or false;
  465. * A pheromone have a level of 0 < pheromone < 1.
  466. * A Pheromone is equal to the probability.
  467. * @param pheromones
  468. * @return
  469. */
  470. private Individual constructASolutionBiasedBy(List<Double> pheromones) {
  471. Individual result = new Individual();
  472. result.position = new ArrayList<Boolean>();
  473. for(double pheromone : pheromones) {
  474. result.position.add((Random.nextDouble() < pheromone));
  475. }
  476. return result;
  477. }
  478. /**
  479. * Initialize Pheromons with 0.5
  480. */
  481. private List<Double> initPheromones(int problemSize) {
  482. List<Double> result = new ArrayList<Double>();
  483. for(int i = 0; i < problemSize;i++) {
  484. result.add(0.5);
  485. }
  486. return result;
  487. }
  488. /**
  489. * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
  490. * Also initialize the Access Hashmap to swap faster positions.
  491. * @param model
  492. * @return
  493. */
  494. private List<Boolean> extractPositionAndAccess() {
  495. Model model = control.getModel();
  496. switchList = new ArrayList<HolonSwitch>();
  497. objectList = new ArrayList<HolonObject>();
  498. List<Boolean> initialState = new ArrayList<Boolean>();
  499. access= new HashMap<Integer, AccessWrapper>();
  500. rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getCurIteration());
  501. resetChain.add(initialState);
  502. return initialState;
  503. }
  504. /**
  505. * Method to extract the Informations recursively out of the Model.
  506. * @param nodes
  507. * @param positionToInit
  508. * @param timeStep
  509. */
  510. private void rollOutNodes(List<AbstractCpsObject> nodes, List<Boolean> positionToInit, int timeStep) {
  511. for(AbstractCpsObject aCps : nodes) {
  512. if (aCps instanceof HolonObject) {
  513. for (HolonElement hE : ((HolonObject) aCps).getElements()) {
  514. positionToInit.add(hE.isActive());
  515. access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
  516. }
  517. objectList.add((HolonObject) aCps);
  518. }
  519. else if (aCps instanceof HolonSwitch) {
  520. HolonSwitch sw = (HolonSwitch) aCps;
  521. positionToInit.add(sw.getState(timeStep));
  522. switchList.add(sw);
  523. access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
  524. }
  525. else if(aCps instanceof CpsUpperNode) {
  526. rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit ,timeStep );
  527. }
  528. }
  529. }
  530. private double evaluatePosition(List<Boolean> position, boolean doIncreaseCounter) {
  531. setState(position);
  532. if(doIncreaseCounter)progressBarStep();
  533. control.calculateStateOnlyForCurrentTimeStep();
  534. DecoratedState actualstate = control.getSimManager().getActualDecorState();
  535. return PSOAlgorithm.getFitnessValueForState(actualstate);
  536. }
  537. /**
  538. * To let the User See the current state without touching the Canvas.
  539. */
  540. private void updateVisual() {
  541. control.calculateStateAndVisualForCurrentTimeStep();
  542. }
  543. /**
  544. * Sets the Model back to its original State before the LAST run.
  545. */
  546. private void resetState() {
  547. setState(resetChain.getLast());
  548. }
  549. /**
  550. * Sets the State out of the given position for calculation or to show the user.
  551. * @param position
  552. */
  553. private void setState(List<Boolean> position) {
  554. for(int i = 0;i<position.size();i++) {
  555. access.get(i).setState(position.get(i));
  556. }
  557. }
  558. private class Individual {
  559. public double fitness;
  560. public List<Boolean> position;
  561. Individual(){};
  562. /**
  563. * Copy Constructor
  564. */
  565. Individual(Individual c){
  566. position = c.position.stream().collect(Collectors.toList());
  567. fitness = c.fitness;
  568. }
  569. }
  570. /**
  571. * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split the List.
  572. */
  573. private class AccessWrapper {
  574. public static final int HOLONELEMENT = 0;
  575. public static final int SWITCH = 1;
  576. private int type;
  577. private HolonSwitch hSwitch;
  578. private HolonElement hElement;
  579. public AccessWrapper(HolonSwitch hSwitch){
  580. type = SWITCH;
  581. this.hSwitch = hSwitch;
  582. }
  583. public AccessWrapper(HolonElement hElement){
  584. type = HOLONELEMENT;
  585. this.hElement = hElement;
  586. }
  587. public void setState(boolean state) {
  588. if(type == HOLONELEMENT) {
  589. hElement.setActive(state);
  590. }else{//is switch
  591. hSwitch.setManualMode(true);
  592. hSwitch.setManualState(state);
  593. }
  594. }
  595. public boolean getState(int timeStep) {
  596. return (type == HOLONELEMENT)?hElement.isActive():hSwitch.getState(timeStep);
  597. }
  598. public int getType() {
  599. return type;
  600. }
  601. }
  602. /**
  603. * A Database for all Global Best(G<sub>Best</sub>) Values in a execution of a the Algo. For Easy Printing.
  604. */
  605. public class RunDataBase {
  606. List<List<Double>> allRuns = new ArrayList<List<Double>>();
  607. /**
  608. * Initialize The Stream before you can write to a File.
  609. */
  610. public void initFileStream() {
  611. File file = fileChooser.getSelectedFile();
  612. try {
  613. file.createNewFile();
  614. BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
  615. new FileOutputStream(file, append), "UTF-8"));
  616. printToStream(out);
  617. out.close();
  618. } catch (IOException e) {
  619. console.println(e.getMessage());
  620. }
  621. }
  622. public void printToStream(BufferedWriter out) throws IOException {
  623. try {
  624. out.write(maxGenerations + 1 + "," + allRuns.size() + "," + popsize);
  625. out.newLine();
  626. }
  627. catch(IOException e) {
  628. console.println(e.getMessage());
  629. }
  630. allRuns.forEach(run -> {
  631. try {
  632. out.write( run.stream().map(Object::toString).collect(Collectors.joining(", ")));
  633. out.newLine();
  634. } catch (IOException e) {
  635. console.println(e.getMessage());
  636. }
  637. } );
  638. }
  639. public List<Double> insertNewRun(){
  640. List<Double> newRun = new ArrayList<Double>();
  641. allRuns.add(newRun);
  642. return newRun;
  643. }
  644. }
  645. private class RunResult {
  646. public int activatedFlex = 0;
  647. public int deactivatedElements = 0;
  648. public float totalCost = 0;
  649. public LinkedList<TimeStepStateResult> timeStepList = new LinkedList<TimeStepStateResult>();
  650. public TimeStepStateResult addTimeStepStateResult(){
  651. TimeStepStateResult aResult = new TimeStepStateResult();
  652. timeStepList.add(aResult);
  653. return aResult;
  654. }
  655. public class TimeStepStateResult{
  656. public int amountOfProducer = 0;
  657. public int amountOfConsumer = 0;
  658. public int amountOfPassiv = 0;
  659. public int amountOfConsumerOverSupplied = 0;
  660. public int amountOfConsumerSupplied = 0;
  661. public int amountOfConsumerPartiallySupplied = 0;
  662. public int amountOfConsumerUnSupplied= 0;
  663. public float getProportionWithState(HolonObjectState state) {
  664. float amountOfObjects = amountOfProducer + amountOfConsumer + amountOfPassiv;
  665. switch(state) {
  666. case NOT_SUPPLIED:
  667. return (float) amountOfConsumerUnSupplied / amountOfObjects;
  668. case NO_ENERGY:
  669. return (float) amountOfPassiv / amountOfObjects;
  670. case OVER_SUPPLIED:
  671. return (float) amountOfConsumerOverSupplied / amountOfObjects;
  672. case PARTIALLY_SUPPLIED:
  673. return (float) amountOfConsumerPartiallySupplied / amountOfObjects;
  674. case PRODUCER:
  675. return (float) amountOfProducer / amountOfObjects;
  676. case SUPPLIED:
  677. return (float) amountOfConsumerSupplied / amountOfObjects;
  678. default:
  679. return 0.f;
  680. }
  681. }
  682. }
  683. public float getAvergaeProportionWithState(HolonObjectState state) {
  684. return timeStepList.stream().map(step -> step.getProportionWithState(state)).reduce((a,b) -> (a + b)).orElse(0.f) / (float) 100;
  685. }
  686. }
  687. /**
  688. * To create Random and maybe switch the random generation in the future.
  689. */
  690. private static class Random{
  691. private static java.util.Random random = new java.util.Random();
  692. /**
  693. * True or false
  694. * @return the random boolean.
  695. */
  696. public static boolean nextBoolean(){
  697. return random.nextBoolean();
  698. }
  699. /**
  700. * Between 0.0(inclusive) and 1.0 (exclusive)
  701. * @return the random double.
  702. */
  703. public static double nextDouble() {
  704. return random.nextDouble();
  705. }
  706. /**
  707. * Random Int in Range [min;max[ with UniformDistirbution
  708. * @param min
  709. * @param max
  710. * @return
  711. */
  712. public static int nextIntegerInRange(int min, int max) {
  713. return min + random.nextInt(max - min);
  714. }
  715. }
  716. private class Handle<T>{
  717. public T object;
  718. Handle(T object){
  719. this.object = object;
  720. }
  721. public String toString() {
  722. return object.toString();
  723. }
  724. }
  725. }