AcoAlgorithm.java 23 KB

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