PSOAlgorithm.java 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102
  1. package exampleAlgorithms;
  2. import java.awt.BorderLayout;
  3. import java.awt.Component;
  4. import java.awt.Cursor;
  5. import java.awt.Dimension;
  6. import java.awt.FlowLayout;
  7. import java.awt.Font;
  8. import java.awt.event.ActionListener;
  9. import java.awt.image.BufferedImage;
  10. import java.io.BufferedWriter;
  11. import java.io.File;
  12. import java.io.FileOutputStream;
  13. import java.io.IOException;
  14. import java.io.OutputStreamWriter;
  15. import java.math.RoundingMode;
  16. import java.text.NumberFormat;
  17. import java.util.ArrayList;
  18. import java.util.HashMap;
  19. import java.util.LinkedList;
  20. import java.util.List;
  21. import java.util.Locale;
  22. import java.util.TreeSet;
  23. import java.util.stream.Collectors;
  24. import javax.swing.BorderFactory;
  25. import javax.swing.ButtonGroup;
  26. import javax.swing.ImageIcon;
  27. import javax.swing.JButton;
  28. import javax.swing.JCheckBox;
  29. import javax.swing.JFileChooser;
  30. import javax.swing.JFormattedTextField;
  31. import javax.swing.JFrame;
  32. import javax.swing.JLabel;
  33. import javax.swing.JOptionPane;
  34. import javax.swing.JPanel;
  35. import javax.swing.JProgressBar;
  36. import javax.swing.JRadioButton;
  37. import javax.swing.JScrollPane;
  38. import javax.swing.JSplitPane;
  39. import javax.swing.JTextArea;
  40. import javax.swing.filechooser.FileNameExtensionFilter;
  41. import javax.swing.text.NumberFormatter;
  42. import api.AddOn;
  43. import classes.AbstractCpsObject;
  44. import classes.CpsUpperNode;
  45. import classes.HolonElement;
  46. import classes.HolonObject;
  47. import classes.HolonSwitch;
  48. import ui.controller.Control;
  49. import ui.model.Model;
  50. import ui.view.Console;
  51. import ui.model.DecoratedHolonObject.HolonObjectState;
  52. import ui.model.DecoratedGroupNode;
  53. import ui.model.DecoratedNetwork;
  54. import ui.model.DecoratedState;
  55. public class PSOAlgorithm implements AddOn {
  56. //Parameter for Algo with default Values:
  57. private int swarmSize = 20;
  58. private int maxIterations = 100;
  59. private double limit = 0.01;
  60. private double dependency = 2.07;
  61. private int rounds = 20;
  62. private int mutationInterval = 1;
  63. private boolean useIntervalMutation = true;
  64. private double mutateProbabilityInterval = 0.01;
  65. private double maxMutationPercent = 0.01;
  66. //Settings For GroupNode using and plotting
  67. private boolean append = false;
  68. private boolean useGroupNode = false;
  69. private DecoratedGroupNode dGroupNode = null;
  70. //Parameter defined by Algo
  71. private HashMap<Integer, AccessWrapper> access;
  72. LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
  73. private double c1, c2, w;
  74. private RunDataBase db;
  75. //Parameter for Plotting (Default Directory in Constructor)
  76. private JFileChooser fileChooser = new JFileChooser();
  77. //Gui Part:
  78. private Control control;
  79. private Console console = new Console();
  80. private JPanel content = new JPanel();
  81. //ProgressBar
  82. private JProgressBar progressBar = new JProgressBar();
  83. private int progressBarCount = 0;
  84. private long startTime;
  85. private Thread runThread = new Thread();
  86. private boolean cancel = false;
  87. public static void main(String[] args)
  88. {
  89. JFrame newFrame = new JFrame("exampleWindow");
  90. PSOAlgorithm instance = new PSOAlgorithm();
  91. newFrame.setContentPane(instance.getPanel());
  92. newFrame.pack();
  93. newFrame.setVisible(true);
  94. newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  95. }
  96. public PSOAlgorithm() {
  97. content.setLayout(new BorderLayout());
  98. JScrollPane scrollPane = new JScrollPane(console);
  99. JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
  100. createOptionPanel() , scrollPane);
  101. splitPane.setResizeWeight(0.0);
  102. content.add(splitPane, BorderLayout.CENTER);
  103. content.setPreferredSize(new Dimension(800,800));
  104. //Default Directory
  105. fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
  106. fileChooser.setSelectedFile(new File("plott.txt"));
  107. }
  108. public JPanel createOptionPanel() {
  109. JPanel optionPanel = new JPanel(new BorderLayout());
  110. JScrollPane scrollPane = new JScrollPane(createParameterPanel());
  111. scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter"));
  112. optionPanel.add(scrollPane, BorderLayout.CENTER);
  113. optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
  114. return optionPanel;
  115. }
  116. private Component createParameterPanel() {
  117. JPanel parameterPanel = new JPanel(null);
  118. parameterPanel.setPreferredSize(new Dimension(510,300));
  119. JLabel info = new JLabel("Tune the variables of the PSO algorithm in order to reach better results.");
  120. info.setBounds(10, 10, 480, 15);
  121. parameterPanel.add(info);
  122. JLabel swarmSizeLabel = new JLabel("Swarm Size:");
  123. swarmSizeLabel.setBounds(20, 60, 100, 20);
  124. parameterPanel.add(swarmSizeLabel);
  125. JLabel maxIterLabel = new JLabel("Max. Iterations:");
  126. maxIterLabel.setBounds(20, 85, 100, 20);
  127. parameterPanel.add(maxIterLabel);
  128. JLabel limitLabel = new JLabel("Limit:");
  129. limitLabel.setBounds(20, 255, 100, 20);
  130. parameterPanel.add(limitLabel);
  131. JLabel dependecyLabel = new JLabel("Dependency:");
  132. dependecyLabel.setBounds(20, 135, 100, 20);
  133. parameterPanel.add(dependecyLabel);
  134. JLabel roundsLabel = new JLabel("Round:");
  135. roundsLabel.setBounds(20, 160, 100, 20);
  136. parameterPanel.add(roundsLabel);
  137. JLabel mutationIntervalLabel = new JLabel("Mutation Interval");
  138. mutationIntervalLabel.setBounds(20, 185, 100, 20);
  139. parameterPanel.add(mutationIntervalLabel);
  140. JLabel cautionLabel = new JLabel(
  141. "Caution: High values in the fields of 'Swarm Size' and 'Max. Iteration' may take some time to calculate.");
  142. cautionLabel.setFont(new Font("Serif", Font.ITALIC, 12));
  143. JLabel showDiagnosticsLabel = new JLabel("Append Plott on existing File:");
  144. showDiagnosticsLabel.setBounds(200, 60, 170, 20);
  145. parameterPanel.add(showDiagnosticsLabel);
  146. JPanel borderPanel = new JPanel(null);
  147. borderPanel.setBounds(200, 85, 185, 50);
  148. borderPanel.setBorder(BorderFactory.createTitledBorder(""));
  149. parameterPanel.add(borderPanel);
  150. JLabel showGroupNodeLabel = new JLabel("Use Group Node:");
  151. showGroupNodeLabel.setBounds(10, 1, 170, 20);
  152. borderPanel.add(showGroupNodeLabel);
  153. JButton selectGroupNodeButton = new JButton("Select GroupNode");
  154. selectGroupNodeButton.setEnabled(false);
  155. selectGroupNodeButton.setBounds(10, 25, 165, 20);
  156. selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode());
  157. borderPanel.add(selectGroupNodeButton);
  158. JCheckBox useGroupNodeCheckBox = new JCheckBox();
  159. useGroupNodeCheckBox.setSelected(false);
  160. useGroupNodeCheckBox.setBounds(155, 1, 25, 20);
  161. useGroupNodeCheckBox.addActionListener(actionEvent -> {
  162. useGroupNode = useGroupNodeCheckBox.isSelected();
  163. selectGroupNodeButton.setEnabled(useGroupNode);
  164. });
  165. borderPanel.add(useGroupNodeCheckBox);
  166. JLabel progressLabel = new JLabel("Progress:");
  167. progressLabel.setBounds(200, 135, 170, 20);
  168. parameterPanel.add(progressLabel);
  169. progressBar.setBounds(200, 155, 185, 20);
  170. progressBar.setStringPainted(true);
  171. parameterPanel.add(progressBar);
  172. cautionLabel.setBounds(10, 210, 500, 15);
  173. parameterPanel.add(cautionLabel);
  174. JCheckBox diagnosticsCheckBox = new JCheckBox();
  175. diagnosticsCheckBox.setSelected(false);
  176. diagnosticsCheckBox.setBounds(370, 60, 25, 20);
  177. diagnosticsCheckBox.addActionListener(actionEvent -> append = diagnosticsCheckBox.isSelected());
  178. parameterPanel.add(diagnosticsCheckBox);
  179. //Integer formatter
  180. NumberFormat format = NumberFormat.getIntegerInstance();
  181. format.setGroupingUsed(false);
  182. format.setParseIntegerOnly(true);
  183. NumberFormatter integerFormatter = new NumberFormatter(format);
  184. integerFormatter.setMinimum(0);
  185. integerFormatter.setCommitsOnValidEdit(true);
  186. JFormattedTextField swarmSizeTextField = new JFormattedTextField(integerFormatter);
  187. swarmSizeTextField.setValue(swarmSize);
  188. swarmSizeTextField.setToolTipText("Only positive Integer.");
  189. swarmSizeTextField.addPropertyChangeListener(actionEvent -> swarmSize = Integer.parseInt(swarmSizeTextField.getValue().toString()));
  190. swarmSizeTextField.setBounds(125, 60, 50, 20);
  191. parameterPanel.add(swarmSizeTextField);
  192. JFormattedTextField maxIterTextField = new JFormattedTextField(integerFormatter);
  193. maxIterTextField.setValue(maxIterations);
  194. maxIterTextField.setToolTipText("Only positive Integer.");
  195. maxIterTextField.addPropertyChangeListener(propertyChange -> maxIterations = Integer.parseInt(maxIterTextField.getValue().toString()));
  196. maxIterTextField.setBounds(125, 85, 50, 20);
  197. parameterPanel.add(maxIterTextField);
  198. //Double Format:
  199. NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
  200. doubleFormat.setMinimumFractionDigits(1);
  201. doubleFormat.setMaximumFractionDigits(3);
  202. doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
  203. //Limit Formatter:
  204. NumberFormatter limitFormatter = new NumberFormatter(doubleFormat);
  205. limitFormatter.setMinimum(0.0);
  206. limitFormatter.setMaximum(1.0);
  207. JFormattedTextField limitTextField = new JFormattedTextField(limitFormatter);
  208. limitTextField.setValue(limit);
  209. limitTextField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
  210. limitTextField.addPropertyChangeListener(propertyChange -> limit = Double.parseDouble(limitTextField.getValue().toString()));
  211. limitTextField.setBounds(125, 255, 50, 20);
  212. parameterPanel.add(limitTextField);
  213. //Limit Formatter:
  214. NumberFormatter dependencyFormatter = new NumberFormatter(doubleFormat);
  215. dependencyFormatter.setMinimum(2.001);
  216. dependencyFormatter.setMaximum(2.4);
  217. JFormattedTextField dependencyTextField = new JFormattedTextField(dependencyFormatter);
  218. dependencyTextField.setValue(dependency);
  219. dependencyTextField.setToolTipText("Only Double in range [2.001, 2.4] with DecimalSeperator Point('.').");
  220. dependencyTextField.addPropertyChangeListener(propertyChange -> dependency = Double.parseDouble(dependencyTextField.getValue().toString()));
  221. dependencyTextField.setBounds(125, 135, 50, 20);
  222. parameterPanel.add(dependencyTextField);
  223. NumberFormatter roundsFormatter = new NumberFormatter(format);
  224. roundsFormatter.setMinimum(1);
  225. roundsFormatter.setCommitsOnValidEdit(true);
  226. JFormattedTextField roundsTextField = new JFormattedTextField(roundsFormatter);
  227. roundsTextField.setValue(rounds);
  228. roundsTextField.setToolTipText("Number of algorithm repetitions for the same starting situation ");
  229. roundsTextField.addPropertyChangeListener(propertyChange -> rounds = Integer.parseInt((roundsTextField.getValue().toString())));
  230. roundsTextField.setBounds(125, 160, 50, 20);
  231. parameterPanel.add(roundsTextField);
  232. //--- subsequently Rolf Did stuff ------------------------------------------------------------------------------------------
  233. /*NumberFormatter mutationIntervalFormatter = new NumberFormatter(inte);
  234. mutationIntervalFormatter.setMinimum(0);
  235. mutationIntervalFormatter.setMaximum(maxIterations);
  236. mutationIntervalFormatter.setCommitsOnValidEdit(true);*/
  237. NumberFormatter mutationFormatter = new NumberFormatter(format);
  238. mutationFormatter.setMinimum(1);
  239. mutationFormatter.setCommitsOnValidEdit(true);
  240. JFormattedTextField mutationIntervalTextfield = new JFormattedTextField(mutationFormatter);
  241. mutationIntervalTextfield.setValue(mutationInterval);
  242. mutationIntervalTextfield.setToolTipText("The number of Iterations after which one mutation iteration is conducted");
  243. mutationIntervalTextfield.addPropertyChangeListener(propertyChange -> mutationInterval = Integer.parseInt((mutationIntervalTextfield.getValue().toString())));
  244. mutationIntervalTextfield.setBounds(125, 185, 50, 20);
  245. parameterPanel.add(mutationIntervalTextfield);
  246. //--- previously Rolf Did stuff ------------------------------------------------------------------------------------------
  247. JLabel mutationIntervallLabel = new JLabel("MutationRate:");
  248. mutationIntervallLabel.setBounds(220, 255, 150, 20);
  249. mutationIntervallLabel.setEnabled(useIntervalMutation);
  250. parameterPanel.add(mutationIntervallLabel);
  251. JFormattedTextField mutationRateField = new JFormattedTextField(limitFormatter);
  252. mutationRateField.setValue(this.mutateProbabilityInterval);
  253. mutationRateField.setEnabled(this.useIntervalMutation);
  254. mutationRateField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
  255. mutationRateField.addPropertyChangeListener(propertyChange -> this.mutateProbabilityInterval = Double.parseDouble(mutationRateField.getValue().toString()));
  256. mutationRateField.setBounds(400, 255, 50, 20);
  257. parameterPanel.add(mutationRateField);
  258. JLabel maxMutationPercentLabel = new JLabel("Max Mutation Percent:");
  259. maxMutationPercentLabel.setBounds(220, 280, 200, 20);
  260. maxMutationPercentLabel.setEnabled(useIntervalMutation);
  261. parameterPanel.add(maxMutationPercentLabel);
  262. JFormattedTextField mutationMaxField = new JFormattedTextField(limitFormatter);
  263. mutationMaxField.setValue(this.maxMutationPercent);
  264. mutationMaxField.setEnabled(this.useIntervalMutation);
  265. mutationMaxField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
  266. mutationMaxField.addPropertyChangeListener(propertyChange -> this.maxMutationPercent = Double.parseDouble(mutationMaxField.getValue().toString()));
  267. mutationMaxField.setBounds(400, 280, 50, 20);
  268. parameterPanel.add(mutationMaxField);
  269. JRadioButton jRadioMutate = new JRadioButton("Normal Mutate");
  270. jRadioMutate.setBounds(20, 230, 200, 20);
  271. jRadioMutate.setSelected(!useIntervalMutation);
  272. jRadioMutate.setActionCommand("normal");
  273. parameterPanel.add(jRadioMutate);
  274. JRadioButton jRadioMutateInterval = new JRadioButton("Mutate Interval");
  275. jRadioMutateInterval.setBounds(220, 230, 200, 20);
  276. jRadioMutateInterval.setActionCommand("intervall");
  277. jRadioMutateInterval.setSelected(useIntervalMutation);
  278. parameterPanel.add(jRadioMutateInterval);
  279. ButtonGroup group = new ButtonGroup();
  280. group.add(jRadioMutate);
  281. group.add(jRadioMutateInterval);
  282. ActionListener radioListener = e -> {
  283. if(e.getActionCommand() == "normal") {
  284. this.useIntervalMutation = false;
  285. limitTextField.setEnabled(true);
  286. limitLabel.setEnabled(true);
  287. mutationIntervallLabel.setEnabled(false);
  288. mutationRateField.setEnabled(false);
  289. maxMutationPercentLabel.setEnabled(false);
  290. mutationMaxField.setEnabled(false);
  291. }else if(e.getActionCommand() == "intervall") {
  292. this.useIntervalMutation = true;
  293. limitTextField.setEnabled(false);
  294. limitLabel.setEnabled(false);
  295. mutationIntervallLabel.setEnabled(true);
  296. mutationRateField.setEnabled(true);
  297. maxMutationPercentLabel.setEnabled(true);
  298. mutationMaxField.setEnabled(true);
  299. }
  300. };
  301. jRadioMutate.addActionListener(radioListener);
  302. jRadioMutateInterval.addActionListener(radioListener);
  303. return parameterPanel;
  304. }
  305. public JPanel createButtonPanel() {
  306. JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  307. JButton cancelButton = new JButton("Cancel Run");
  308. cancelButton.addActionListener(actionEvent -> cancel());
  309. buttonPanel.add(cancelButton);
  310. JButton folderButton = new JButton("Change Plott-File");
  311. folderButton.addActionListener(actionEvent -> setSaveFile());
  312. buttonPanel.add(folderButton);
  313. JButton fitnessButton = new JButton("Actual Fitness");
  314. fitnessButton.addActionListener(actionEvent -> fitness());
  315. buttonPanel.add(fitnessButton);
  316. JButton plottButton = new JButton("Plott");
  317. plottButton.addActionListener(actionEvent -> plott());
  318. buttonPanel.add(plottButton);
  319. JButton resetButton = new JButton("Reset");
  320. resetButton.setToolTipText("Resets the State to before the Algorithm has runed.");
  321. resetButton.addActionListener(actionEvent -> resetAll());
  322. buttonPanel.add(resetButton);
  323. JButton runButton = new JButton("Run");
  324. runButton.addActionListener(actionEvent -> {
  325. Runnable task = () -> run();
  326. runThread = new Thread(task);
  327. runThread.start();
  328. });
  329. buttonPanel.add(runButton);
  330. return buttonPanel;
  331. }
  332. private void run() {
  333. cancel = false;
  334. disableGuiInput(true);
  335. startTimer();
  336. executePsoAlgoWithCurrentParameters();
  337. if(cancel) {
  338. resetLast();
  339. disableGuiInput(false);
  340. return;
  341. }
  342. printElapsedTime();
  343. disableGuiInput(false);
  344. }
  345. private void disableGuiInput(boolean bool) {
  346. control.guiDisable(bool);
  347. }
  348. private void cancel() {
  349. if(runThread.isAlive()) {
  350. console.println("");
  351. console.println("Cancel run.");
  352. cancel = true;
  353. progressBar.setValue(0);
  354. } else {
  355. console.println("Nothing to cancel.");
  356. }
  357. }
  358. private void fitness() {
  359. if(runThread.isAlive()) {
  360. console.println("Run have to be cancelled First.");
  361. return;
  362. }
  363. initDependentParameter();
  364. double currentFitness = evaluatePosition(extractPositionAndAccess(control.getModel()), false);
  365. resetChain.removeLast();
  366. console.println("Actual Fitnessvalue: " + currentFitness);
  367. }
  368. private void setSaveFile() {
  369. fileChooser.setFileFilter(new FileNameExtensionFilter("File", "txt"));
  370. fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
  371. int result = fileChooser.showSaveDialog(content);
  372. if(result == JFileChooser.APPROVE_OPTION) {
  373. console.println("Set save File to:" + fileChooser.getSelectedFile().getAbsolutePath());
  374. }
  375. }
  376. private void plott() {
  377. if(db!=null) {
  378. console.println("Plott..");
  379. db.initFileStream();
  380. }else {
  381. console.println("No run inistialized.");
  382. }
  383. }
  384. private void resetLast() {
  385. if(runThread.isAlive()) {
  386. console.println("Run have to be cancelled First.");
  387. return;
  388. }
  389. if(!resetChain.isEmpty()) {
  390. console.println("Resetting..");
  391. resetState();
  392. resetChain.removeLast();
  393. control.resetSimulation();
  394. updateVisual();
  395. }else {
  396. console.println("No run inistialized.");
  397. }
  398. }
  399. private void resetAll() {
  400. if(runThread.isAlive()) {
  401. console.println("Run have to be cancelled First.");
  402. return;
  403. }
  404. if(!resetChain.isEmpty()) {
  405. console.println("Resetting..");
  406. setState(resetChain.getFirst());
  407. resetChain.clear();
  408. control.resetSimulation();
  409. control.setCurIteration(0);
  410. updateVisual();
  411. }else {
  412. console.println("No run inistialized.");
  413. }
  414. }
  415. private void printParameter() {
  416. console.println("SwarmSize:" + swarmSize + ", MaxIter:" + maxIterations + ", Limit:" + limit + ", Dependency:" + dependency + ", Rounds:" + rounds +", DependentParameter: w:"+ w + ", c1:" + c1 + ", c2:" + c2 );
  417. }
  418. @Override
  419. public JPanel getPanel() {
  420. return content;
  421. }
  422. @Override
  423. public void setController(Control control) {
  424. this.control = control;
  425. }
  426. private void selectGroupNode() {
  427. Object[] possibilities = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().values().stream().map(aCps -> new Handle<DecoratedGroupNode>(aCps)).toArray();
  428. @SuppressWarnings("unchecked")
  429. 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, "");
  430. if(selected != null) {
  431. console.println("Selected: " + selected);
  432. dGroupNode = selected.object;
  433. }
  434. }
  435. private void progressBarStep(){
  436. progressBar.setValue(++progressBarCount);
  437. }
  438. private void calculateProgressBarParameter() {
  439. int max = swarmSize * (maxIterations + 1)* rounds + rounds;
  440. progressBarCount = 0;
  441. progressBar.setValue(0);
  442. progressBar.setMaximum(max);
  443. }
  444. private void startTimer(){
  445. startTime = System.currentTimeMillis();
  446. }
  447. private void printElapsedTime(){
  448. long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
  449. console.println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds);
  450. }
  451. //Algo Part:
  452. /**
  453. * The Execution of the Algo its initialize the missing parameter and execute single Algo runs successively.
  454. */
  455. private void executePsoAlgoWithCurrentParameters() {
  456. initDependentParameter();
  457. calculateProgressBarParameter();
  458. printParameter();
  459. Best runBest = new Best();
  460. runBest.value = Double.MAX_VALUE;
  461. db = new RunDataBase();
  462. for(int r = 0; r < rounds; r++)
  463. {
  464. List<Double> runList = db.insertNewRun();
  465. Best lastRunBest = executePSOoneTime(runList);
  466. if(cancel)return;
  467. resetState();
  468. if(lastRunBest.value < runBest.value) runBest = lastRunBest;
  469. }
  470. console.println("AlgoResult:" + runBest.value);
  471. //console.println("[" + lastRunBest.position.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]");
  472. setState(runBest.position);
  473. updateVisual();
  474. }
  475. /**
  476. * Calculate w, c1, c2
  477. */
  478. private void initDependentParameter() {
  479. w = 1.0 / (dependency - 1 + Math.sqrt(dependency * dependency - 2 * dependency));
  480. c1 = c2 = dependency * w;
  481. }
  482. /**
  483. * <p>Algo from Paper:</p><font size="3"><pre>
  484. *
  485. * Begin
  486. * t = 0; {t: generation index}
  487. * initialize particles x<sub>p,i,j</sub>(t);
  488. * evaluation x<sub>p,i,j</sub>(t);
  489. * while (termination condition &ne; true) do
  490. * v<sub>i,j</sub>(t) = update v<sub>i,j</sub>(t); {by Eq. (6)}
  491. * x<sub>g,i,j</sub>(t) = update x<sub>g,i,j</sub>(t); {by Eq. (7)}
  492. * x<sub>g,i,j</sub>(t) = mutation x<sub>g,i,j</sub>(t); {by Eq. (11)}
  493. * x<sub>p,i,j</sub>(t) = decode x<sub>g,i,j</sub>(t); {by Eqs. (8) and (9)}
  494. * evaluate x<sub>p,i,j</sub>(t);
  495. * t = t + 1;
  496. * end while
  497. * End</pre></font>
  498. * <p>with:</p><font size="3">
  499. *
  500. * x<sub>g,i,j</sub>: genotype ->genetic information -> in continuous space<br>
  501. * x<sub>p,i,j</sub>: phenotype -> observable characteristics-> in binary space<br>
  502. * X<sub>g,max</sub>: is the Maximum here set to 4.<br>
  503. * Eq. (6):v<sub>i,j</sub>(t + 1) = wv<sub>i,j</sub>+c<sub>1</sub>R<sub>1</sub>(P<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))+c<sub>2</sub>R<sub>2</sub>(g<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))<br>
  504. * Eq. (7):x<sub>g,i,j</sub>(t + 1) = x<sub>g,i,j</sub>(t) + v<sub>i,j</sub>(t + 1)<br>
  505. * Eq. (11):<b>if(</b>rand()&lt;r<sub>mu</sub><b>)then</b> x<sub>g,i,j</sub>(t + 1) = -x<sub>g,i,j</sub>(t + 1)<br>
  506. * Eq. (8):x<sub>p,i,j</sub>(t + 1) = <b>(</b>rand() &lt; S(x<sub>g,i,j</sub>(t + 1))<b>) ?</b> 1 <b>:</b> 0<br>
  507. * Eq. (9) Sigmoid:S(x<sub>g,i,j</sub>(t + 1)) := 1/(1 + e<sup>-x<sub>g,i,j</sub>(t + 1)</sup>)<br></font>
  508. * <p>Parameter:</p>
  509. * w inertia, calculated from phi(Variable:{@link #dependency})<br>
  510. * c1: influence, calculated from phi(Variable:{@link #dependency}) <br>
  511. * c2: influence, calculated from phi(Variable:{@link #dependency})<br>
  512. * r<sub>mu</sub>: probability that the proposed operation is conducted defined by limit(Variable:{@link #limit})<br>
  513. *
  514. *
  515. */
  516. private Best executePSOoneTime(List<Double> runList) {
  517. Best globalBest = new Best();
  518. globalBest.position = extractPositionAndAccess(control.getModel());
  519. globalBest.value = evaluatePosition(globalBest.position, true);
  520. console.println("Start Value:" + globalBest.value);
  521. int dimensions = globalBest.position.size();
  522. List<Particle> swarm= initializeParticles(dimensions);
  523. runList.add(globalBest.value);
  524. evaluation(globalBest, swarm);
  525. runList.add(globalBest.value);
  526. for (int iteration = 0; iteration < maxIterations ; iteration++) {
  527. int mutationAllowed = iteration % mutationInterval;
  528. for (int particleNumber = 0; particleNumber < swarmSize; particleNumber++) {
  529. Particle particle = swarm.get(particleNumber);
  530. if(this.useIntervalMutation) {
  531. boolean allowMutation = (Random.nextDouble() < this.mutateProbabilityInterval);
  532. TreeSet<Integer> mutationLocation = null;
  533. if(allowMutation)mutationLocation = locationsToMutate(dimensions);
  534. for(int index = 0; index < dimensions; index++) {
  535. updateVelocity(particle, index, globalBest);
  536. updateGenotype(particle, index);
  537. if(allowMutation &&mutationAllowed == 0 && iteration != 0 && mutationLocation.contains(index))mutation(particle, index);
  538. decode(particle, index);
  539. }
  540. }else {
  541. for(int index = 0; index < dimensions; index++) {
  542. updateVelocity(particle, index, globalBest);
  543. updateGenotype(particle, index);
  544. if(mutationAllowed == 0 && iteration != 0)mutation(particle, index);
  545. decode(particle, index);
  546. }
  547. }
  548. }
  549. if(cancel)return null;
  550. evaluation(globalBest, swarm);
  551. runList.add(globalBest.value);
  552. }
  553. console.println(" End Value:" + globalBest.value);
  554. return globalBest;
  555. }
  556. private TreeSet<Integer> locationsToMutate(int dimensions) {
  557. TreeSet<Integer> mutationLocation = new TreeSet<Integer>(); //sortedSet
  558. int maximumAmountOfMutatedBits = Math.max(1, (int)Math.round(((double) dimensions) * this.maxMutationPercent));
  559. int randomUniformAmountOfMutatedValues = Random.nextIntegerInRange(1,maximumAmountOfMutatedBits + 1);
  560. for(int i = 0; i< randomUniformAmountOfMutatedValues; i++) {
  561. boolean success = mutationLocation.add(Random.nextIntegerInRange(0, dimensions));
  562. if(!success) i--; //can be add up to some series long loops if maximumAmountOfMutatedBits get closed to problemsize.
  563. }
  564. //console.println(mutationLocation.toString());
  565. return mutationLocation;
  566. }
  567. /**
  568. * Eq. (6):v<sub>i,j</sub>(t + 1) = wv<sub>i,j</sub>+c<sub>1</sub>R<sub>1</sub>(P<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))+c<sub>2</sub>R<sub>2</sub>(g<sub>best,i,j</sub>-x<sub>p,i,j</sub>(t))<br>
  569. * @param particle
  570. * @param index
  571. * @param globalBest
  572. */
  573. private void updateVelocity(Particle particle, int index, Best globalBest) {
  574. double r1 = Random.nextDouble();
  575. double r2 = Random.nextDouble();
  576. double posValue = particle.xPhenotype.get(index)?1.0:0.0;
  577. particle.velocity.set(index, clamp(w*particle.velocity.get(index) + c1*r1*((particle.localBest.position.get(index)?1.0:0.0) - posValue) + c2*r2*((globalBest.position.get(index)?1.0:0.0)- posValue)) );
  578. }
  579. /**
  580. * Eq. (7):x<sub>g,i,j</sub>(t + 1) = x<sub>g,i,j</sub>(t) + v<sub>i,j</sub>(t + 1)<br>
  581. * @param particle
  582. * @param index
  583. */
  584. private void updateGenotype(Particle particle, int index) {
  585. particle.xGenotype.set(index, clamp(particle.xGenotype.get(index) + particle.velocity.get(index)));
  586. }
  587. /**
  588. * Eq. (11):<b>if(</b>rand()&lt;r<sub>mu</sub><b>)then</b> x<sub>g,i,j</sub>(t + 1) = -x<sub>g,i,j</sub>(t + 1)<br>
  589. * @param particle
  590. * @param index
  591. */
  592. private void mutation(Particle particle, int index) {
  593. if(Random.nextDouble() < limit) particle.xGenotype.set(index, -particle.xGenotype.get(index));
  594. }
  595. /**
  596. * Eq. (8):x<sub>p,i,j</sub>(t + 1) = <b>(</b>rand() &lt; S(x<sub>g,i,j</sub>(t + 1))<b>) ?</b> 1 <b>:</b> 0<br>
  597. * @param particle
  598. * @param index
  599. */
  600. private void decode(Particle particle, int index) {
  601. particle.xPhenotype.set(index, Random.nextDouble() < Sigmoid(particle.xGenotype.get(index)));
  602. }
  603. /**
  604. * Eq. (9) Sigmoid:S(x<sub>g,i,j</sub>(t + 1)) := 1/(1 + e<sup>-x<sub>g,i,j</sub>(t + 1)</sup>)<br></font>
  605. * @param value
  606. * @return
  607. */
  608. private double Sigmoid(double value) {
  609. return 1.0 / (1.0 + Math.exp(-value));
  610. }
  611. /**
  612. * To clamp X<sub>g,j,i</sub> and v<sub>i,j</sub> in Range [-X<sub>g,max</sub>|+X<sub>g,max</sub>] with {X<sub>g,max</sub>= 4}
  613. * @param value
  614. * @return
  615. */
  616. private double clamp(double value) {
  617. return Math.max(-4.0, Math.min(4.0, value));
  618. }
  619. /**
  620. *
  621. * @param j maximum index of position in the particle
  622. * @return
  623. */
  624. private List<Particle> initializeParticles(int j) {
  625. List<Particle> swarm = new ArrayList<Particle>();
  626. //Create The Particle
  627. for (int particleNumber = 0; particleNumber < swarmSize; particleNumber++){
  628. //Create a Random position
  629. List<Boolean> aRandomPosition = new ArrayList<Boolean>();
  630. for (int index = 0; index < j; index++){
  631. aRandomPosition.add(Random.nextBoolean());
  632. }
  633. swarm.add(new Particle(aRandomPosition));
  634. }
  635. return swarm;
  636. }
  637. /**
  638. * Evaluate each particle and update the global Best position;
  639. * @param globalBest
  640. * @param swarm
  641. */
  642. private void evaluation(Best globalBest, List<Particle> swarm) {
  643. for(Particle p: swarm) {
  644. double localEvaluationValue = evaluatePosition(p.xPhenotype, true);
  645. p.checkNewEvaluationValue(localEvaluationValue);
  646. if(localEvaluationValue < globalBest.value) {
  647. globalBest.value = localEvaluationValue;
  648. globalBest.position = p.localBest.position;
  649. }
  650. }
  651. }
  652. /**
  653. * Evaluate a position.
  654. * @param position
  655. * @return
  656. */
  657. private double evaluatePosition(List<Boolean> position, boolean doIncreaseCounter) {
  658. setState(position);
  659. if(doIncreaseCounter)progressBarStep();
  660. control.calculateStateOnlyForCurrentTimeStep();
  661. DecoratedState actualstate = control.getSimManager().getActualDecorState();
  662. return getFitnessValueForState(actualstate);
  663. }
  664. /**
  665. * Calculate the Fitness(Penelty) Value for a state (alias the calculated Position).
  666. * TODO: Make me better Rolf.
  667. * @param state
  668. * @return
  669. */
  670. public static double getFitnessValueForState(DecoratedState state) {
  671. double fitness = 0.0;
  672. double nw_fitness =0.0;
  673. double object_fitness = 0.0;
  674. // calculate network_fitness
  675. for(DecoratedNetwork net : state.getNetworkList()) {
  676. float production = net.getSupplierList().stream().map(supplier -> supplier.getEnergyToSupplyNetwork()).reduce(0.0f, (a, b) -> a + b);
  677. float consumption = net.getConsumerList().stream().map(con -> con.getEnergyNeededFromNetwork()).reduce(0.0f, (a, b) -> a + b);
  678. nw_fitness += Math.abs((production - consumption)/100); //Energy is now everywhere positive
  679. }
  680. // calculate object_fitness
  681. for(DecoratedNetwork net : state.getNetworkList()) {
  682. object_fitness += net.getConsumerList().stream().map(con -> holonObjectSupplyPenaltyFunction(con.getSupplyBarPercentage()) + inactiveHolonElementPenalty(con.getModel())).reduce(0.0, (a, b) -> (a + b));
  683. //warum war das im network fitness und nicht hier im Object fitness??
  684. object_fitness += net.getConsumerList().stream().map(con -> StateToDouble(con.getState())).reduce(0.0, (a,b) -> (a+b));
  685. //System.out.console.println("objectfitness for statestuff: " + object_fitness);
  686. //object_fitness += net.getPassivNoEnergyList().stream().map(con -> 1000.0).reduce(0.0, (a, b) -> (a + b));
  687. object_fitness += net.getPassivNoEnergyList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b));
  688. object_fitness += net.getSupplierList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b));
  689. object_fitness += net.getConsumerSelfSuppliedList().stream().map(con -> inactiveHolonElementPenalty(con.getModel())).reduce(0.0, (a, b) -> (a + b));
  690. }
  691. fitness = nw_fitness + object_fitness;
  692. return fitness;
  693. }
  694. /**
  695. * Untouched:
  696. * Function that returns the fitness depending on the number of elements deactivated in a single holon object
  697. * @param obj Holon Object that contains Holon Elements
  698. * @return fitness value for that object depending on the number of deactivated holon elements
  699. */
  700. private static double inactiveHolonElementPenalty(HolonObject obj) {
  701. float result = 0;
  702. int activeElements = obj.getNumberOfActiveElements();
  703. int maxElements = obj.getElements().size();
  704. //result = (float) Math.pow((maxElements -activeElements),2)*10;
  705. result = (float) Math.pow(5, 4* ( (float) maxElements - (float) activeElements)/ (float) maxElements) - 1;
  706. //System.out.console.println("max: " + maxElements + " active: " + activeElements + " results in penalty: " + result);
  707. return result;
  708. }
  709. /**
  710. * Untouched:
  711. * Calculates a penalty value based on the HOs current supply percentage
  712. * @param supplyPercentage
  713. * @return
  714. */
  715. private static double holonObjectSupplyPenaltyFunction(float supplyPercentage) {
  716. double result = 0;
  717. /*if(supplyPercentage == 1)
  718. return result;
  719. else if(supplyPercentage < 1 && supplyPercentage >= 0.25) // undersupplied inbetween 25% and 100%
  720. result = (float) Math.pow(1/supplyPercentage, 2);
  721. else if (supplyPercentage < 0.25) //undersupplied with less than 25%
  722. result = (float) Math.pow(1/supplyPercentage,2);
  723. else if (supplyPercentage < 1.25) //Oversupplied less than 25%
  724. result = (float) Math.pow(supplyPercentage,3) ;
  725. else result = (float) Math.pow(supplyPercentage,4); //Oversupplied more than 25%
  726. if(Float.isInfinite(result) || Float.isNaN(result))
  727. result = 1000;
  728. */
  729. if(supplyPercentage <= 1.0) {
  730. result = Math.pow(5,((100 - (supplyPercentage*100))/50 + 2)) - Math.pow(5, 2);
  731. }
  732. else {
  733. result = Math.pow(6,((100 - (supplyPercentage*100))/50 + 2)) - Math.pow(6, 2);
  734. }
  735. return result;
  736. }
  737. /**
  738. * If you want to get in touch with a reliable state? Working function not in use currently.
  739. * @param state
  740. * @return
  741. */
  742. private static double StateToDouble(HolonObjectState state) {
  743. switch (state) {
  744. case NOT_SUPPLIED:
  745. return 150.0;
  746. case NO_ENERGY:
  747. return 150.0;
  748. case OVER_SUPPLIED:
  749. return 100.0;
  750. case PARTIALLY_SUPPLIED:
  751. return 100.0;
  752. case PRODUCER:
  753. return 0;
  754. case SUPPLIED:
  755. return 0;
  756. default:
  757. return 0;
  758. }
  759. }
  760. /**
  761. * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
  762. * Also initialize the Access Hashmap to swap faster positions.
  763. * @param model
  764. * @return
  765. */
  766. private List<Boolean> extractPositionAndAccess(Model model) {
  767. List<Boolean> initialState = new ArrayList<Boolean>();
  768. access= new HashMap<Integer, AccessWrapper>();
  769. rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getCurIteration());
  770. resetChain.add(initialState);
  771. return initialState;
  772. }
  773. /**
  774. * Method to extract the Informations recursively out of the Model.
  775. * @param nodes
  776. * @param positionToInit
  777. * @param timeStep
  778. */
  779. private void rollOutNodes(List<AbstractCpsObject> nodes, List<Boolean> positionToInit, int timeStep) {
  780. for(AbstractCpsObject aCps : nodes) {
  781. if (aCps instanceof HolonObject) {
  782. for (HolonElement hE : ((HolonObject) aCps).getElements()) {
  783. positionToInit.add(hE.isActive());
  784. access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
  785. }
  786. }
  787. else if (aCps instanceof HolonSwitch) {
  788. HolonSwitch sw = (HolonSwitch) aCps;
  789. positionToInit.add(sw.getState(timeStep));
  790. access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
  791. }
  792. else if(aCps instanceof CpsUpperNode) {
  793. rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit ,timeStep );
  794. }
  795. }
  796. }
  797. /**
  798. * To let the User See the current state without touching the Canvas.
  799. */
  800. private void updateVisual() {
  801. control.calculateStateAndVisualForCurrentTimeStep();
  802. control.updateCanvas();
  803. }
  804. /**
  805. * Sets the Model back to its original State before the LAST run.
  806. */
  807. private void resetState() {
  808. setState(resetChain.getLast());
  809. }
  810. /**
  811. * Sets the State out of the given position for calculation or to show the user.
  812. * @param position
  813. */
  814. private void setState(List<Boolean> position) {
  815. for(int i = 0;i<position.size();i++) {
  816. access.get(i).setState(position.get(i));
  817. }
  818. }
  819. /**
  820. * A Database for all Global Best(G<sub>Best</sub>) Values in a execution of a the Algo. For Easy Printing.
  821. */
  822. public class RunDataBase {
  823. List<List<Double>> allRuns = new ArrayList<List<Double>>();
  824. /**
  825. * Initialize The Stream before you can write to a File.
  826. */
  827. public void initFileStream() {
  828. File file = fileChooser.getSelectedFile();
  829. try {
  830. file.createNewFile();
  831. BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
  832. new FileOutputStream(file, append), "UTF-8"));
  833. printToStream(out);
  834. out.close();
  835. } catch (IOException e) {
  836. console.println(e.getMessage());
  837. }
  838. }
  839. /**
  840. *
  841. * TODO: Rolf Change this method to suit your Python script respectively.
  842. * A run have maxIterations + 2 values. As described: First is the InitialState Value,
  843. * Second is The best Value after the swarm is Initialized not have moved jet, and then comes the Iterations that described
  844. * each step of movement from the swarm.
  845. */
  846. public void printToStream(BufferedWriter out) throws IOException {
  847. try {
  848. out.write(maxIterations + 2 + "," + allRuns.size() + "," + swarmSize);
  849. out.newLine();
  850. }
  851. catch(IOException e) {
  852. console.println(e.getMessage());
  853. }
  854. allRuns.forEach(run -> {
  855. try {
  856. out.write( run.stream().map(Object::toString).collect(Collectors.joining(", ")));
  857. out.newLine();
  858. } catch (IOException e) {
  859. console.println(e.getMessage());
  860. }
  861. } );
  862. }
  863. public List<Double> insertNewRun(){
  864. List<Double> newRun = new ArrayList<Double>();
  865. allRuns.add(newRun);
  866. return newRun;
  867. }
  868. }
  869. /**
  870. * To give the Local Best of a Partice(P<sub>Best</sub>) or the Global Best(G<sub>Best</sub>) a Wrapper to have Position And Evaluation Value in one Place.
  871. */
  872. private class Best{
  873. public double value;
  874. public List<Boolean> position;
  875. public Best(){
  876. }
  877. }
  878. /**
  879. * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split the List.
  880. */
  881. private class AccessWrapper {
  882. public static final int HOLONELEMENT = 0;
  883. public static final int SWITCH = 1;
  884. private int type;
  885. private HolonSwitch hSwitch;
  886. private HolonElement hElement;
  887. public AccessWrapper(HolonSwitch hSwitch){
  888. type = SWITCH;
  889. this.hSwitch = hSwitch;
  890. }
  891. public AccessWrapper(HolonElement hElement){
  892. type = HOLONELEMENT;
  893. this.hElement = hElement;
  894. }
  895. public void setState(boolean state) {
  896. if(type == HOLONELEMENT) {
  897. hElement.setActive(state);
  898. }else{//is switch
  899. hSwitch.setManualMode(true);
  900. hSwitch.setManualState(state);
  901. }
  902. }
  903. public boolean getState(int timeStep) {
  904. return (type == HOLONELEMENT)?hElement.isActive():hSwitch.getState(timeStep);
  905. }
  906. }
  907. /**
  908. * Class to represent a Particle.
  909. */
  910. private class Particle{
  911. /**
  912. * The velocity of a particle.
  913. */
  914. public List<Double> velocity;
  915. /**
  916. * The positions genotype.
  917. */
  918. public List<Double> xGenotype;
  919. /**
  920. * The positions phenotype. Alias the current position.
  921. */
  922. public List<Boolean> xPhenotype;
  923. public Best localBest;
  924. Particle(List<Boolean> position){
  925. this.xPhenotype = position;
  926. //Init velocity, xGenotype with 0.0 values.
  927. this.velocity = position.stream().map(bool -> 0.0).collect(Collectors.toList());
  928. this.xGenotype = position.stream().map(bool -> 0.0).collect(Collectors.toList());
  929. localBest = new Best();
  930. localBest.value = Double.MAX_VALUE;
  931. }
  932. public void checkNewEvaluationValue(double newEvaluationValue) {
  933. if(newEvaluationValue < localBest.value) {
  934. localBest.value = newEvaluationValue;
  935. localBest.position = xPhenotype.stream().map(bool -> bool).collect(Collectors.toList());
  936. }
  937. }
  938. public String toString() {
  939. return "Particle with xPhenotype(Position), xGenotype, velocity:["
  940. + listToString(xPhenotype) + "],[" + listToString(xGenotype) + "],["
  941. + listToString(velocity) + "]";
  942. }
  943. private <Type> String listToString(List<Type> list) {
  944. return list.stream().map(Object::toString).collect(Collectors.joining(", "));
  945. }
  946. }
  947. /**
  948. * To create Random and maybe switch the random generation in the future.
  949. */
  950. private static class Random{
  951. private static java.util.Random random = new java.util.Random();
  952. /**
  953. * True or false
  954. * @return the random boolean.
  955. */
  956. public static boolean nextBoolean(){
  957. return random.nextBoolean();
  958. }
  959. /**
  960. * Between 0.0(inclusive) and 1.0 (exclusive)
  961. * @return the random double.
  962. */
  963. public static double nextDouble() {
  964. return random.nextDouble();
  965. }
  966. /**
  967. * Random Int in Range [min;max[ with UniformDistirbution
  968. * @param min
  969. * @param max
  970. * @return
  971. */
  972. public static int nextIntegerInRange(int min, int max) {
  973. return min + random.nextInt(max - min);
  974. }
  975. }
  976. private class Handle<T>{
  977. public T object;
  978. Handle(T object){
  979. this.object = object;
  980. }
  981. public String toString() {
  982. return object.toString();
  983. }
  984. }
  985. }