|
@@ -0,0 +1,320 @@
|
|
|
|
+package exampleAlgorithms;
|
|
|
|
+
|
|
|
|
+import java.awt.BorderLayout;
|
|
|
|
+import java.awt.Component;
|
|
|
|
+import java.awt.Dimension;
|
|
|
|
+import java.awt.FlowLayout;
|
|
|
|
+import java.awt.Font;
|
|
|
|
+import java.awt.GridBagConstraints;
|
|
|
|
+import java.awt.GridBagLayout;
|
|
|
|
+import java.math.RoundingMode;
|
|
|
|
+import java.text.DecimalFormat;
|
|
|
|
+import java.text.NumberFormat;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.ListIterator;
|
|
|
|
+import java.util.Locale;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
+
|
|
|
|
+import javax.swing.BorderFactory;
|
|
|
|
+import javax.swing.JButton;
|
|
|
|
+import javax.swing.JCheckBox;
|
|
|
|
+import javax.swing.JFormattedTextField;
|
|
|
|
+import javax.swing.JFrame;
|
|
|
|
+import javax.swing.JLabel;
|
|
|
|
+import javax.swing.JPanel;
|
|
|
|
+import javax.swing.JScrollPane;
|
|
|
|
+import javax.swing.JSplitPane;
|
|
|
|
+import javax.swing.JTextArea;
|
|
|
|
+import javax.swing.JTextField;
|
|
|
|
+import javax.swing.text.NumberFormatter;
|
|
|
|
+
|
|
|
|
+import api.Algorithm;
|
|
|
|
+import classes.AbstractCpsObject;
|
|
|
|
+import classes.CpsEdge;
|
|
|
|
+import classes.CpsNode;
|
|
|
|
+import classes.CpsUpperNode;
|
|
|
|
+import classes.HolonElement;
|
|
|
|
+import classes.HolonObject;
|
|
|
|
+import classes.HolonSwitch;
|
|
|
|
+import ui.controller.Control;
|
|
|
|
+import ui.model.IntermediateCableWithState;
|
|
|
|
+import ui.model.Model;
|
|
|
|
+import ui.model.DecoratedCable.CableState;
|
|
|
|
+
|
|
|
|
+public class PSOAlgotihm implements Algorithm {
|
|
|
|
+
|
|
|
|
+ private int swarmSize = 20;
|
|
|
|
+ private int maxIterations = 100;
|
|
|
|
+ private double limit = 1.0;
|
|
|
|
+ private double dependency = 2.01;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private Control control;
|
|
|
|
+ private JTextArea textArea;
|
|
|
|
+ private JPanel content = new JPanel();
|
|
|
|
+ public static void main(String[] args)
|
|
|
|
+ {
|
|
|
|
+ JFrame newFrame = new JFrame("exampleWindow");
|
|
|
|
+ PSOAlgotihm instance = new PSOAlgotihm();
|
|
|
|
+ newFrame.setContentPane(instance.getAlgorithmPanel());
|
|
|
|
+ newFrame.pack();
|
|
|
|
+ newFrame.setVisible(true);
|
|
|
|
+ newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
|
+ }
|
|
|
|
+ public PSOAlgotihm() {
|
|
|
|
+ content.setLayout(new BorderLayout());
|
|
|
|
+
|
|
|
|
+ textArea = new JTextArea();
|
|
|
|
+ textArea.setEditable(false);
|
|
|
|
+ JScrollPane scrollPane = new JScrollPane(textArea);
|
|
|
|
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
|
|
|
|
+ createOptionPanel() , scrollPane);
|
|
|
|
+ splitPane.setResizeWeight(0.9);
|
|
|
|
+ content.add(splitPane, BorderLayout.CENTER);
|
|
|
|
+ content.setPreferredSize(new Dimension(800,800));
|
|
|
|
+ }
|
|
|
|
+ public JPanel createOptionPanel() {
|
|
|
|
+ JPanel optionPanel = new JPanel(new BorderLayout());
|
|
|
|
+ JScrollPane scrollPane = new JScrollPane(createParameterPanel());
|
|
|
|
+ scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter"));
|
|
|
|
+ optionPanel.add(scrollPane, BorderLayout.CENTER);
|
|
|
|
+ optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
|
|
|
|
+ return optionPanel;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Component createParameterPanel() {
|
|
|
|
+ JPanel parameterPanel = new JPanel(null);
|
|
|
|
+ parameterPanel.setPreferredSize(new Dimension(510,300));
|
|
|
|
+
|
|
|
|
+ JLabel info = new JLabel("Tune the variables of the PSO algorithm in order to reach better results.");
|
|
|
|
+ info.setBounds(10, 10, 480, 15);
|
|
|
|
+ parameterPanel.add(info);
|
|
|
|
+
|
|
|
|
+ JLabel swarmSizeLabel = new JLabel("Swarm Size:");
|
|
|
|
+ swarmSizeLabel.setBounds(20, 60, 100, 20);
|
|
|
|
+ parameterPanel.add(swarmSizeLabel);
|
|
|
|
+
|
|
|
|
+ JLabel showDiagnosticsLabel = new JLabel("Show Diagnostic:");
|
|
|
|
+ showDiagnosticsLabel.setBounds(200, 60, 110, 20);
|
|
|
|
+ parameterPanel.add(showDiagnosticsLabel);
|
|
|
|
+
|
|
|
|
+ JLabel cautionLabel = new JLabel(
|
|
|
|
+ "Caution: High values in the fields of 'Swarm Size' and 'Max. Iteration' may take some time to calculate.");
|
|
|
|
+ cautionLabel.setFont(new Font("Serif", Font.ITALIC, 12));
|
|
|
|
+ cautionLabel.setBounds(10, 210, 500, 15);
|
|
|
|
+ parameterPanel.add(cautionLabel);
|
|
|
|
+
|
|
|
|
+ JLabel maxIterLabel = new JLabel("Max. Iterations:");
|
|
|
|
+ maxIterLabel.setBounds(20, 85, 100, 20);
|
|
|
|
+ parameterPanel.add(maxIterLabel);
|
|
|
|
+
|
|
|
|
+ JLabel limitLabel = new JLabel("Limit:");
|
|
|
|
+ limitLabel.setBounds(20, 110, 100, 20);
|
|
|
|
+ parameterPanel.add(limitLabel);
|
|
|
|
+
|
|
|
|
+ JLabel dependecyLabel = new JLabel("Dependency:");
|
|
|
|
+ dependecyLabel.setBounds(20, 135, 100, 20);
|
|
|
|
+ parameterPanel.add(dependecyLabel);
|
|
|
|
+
|
|
|
|
+ JCheckBox diagnosticsCheckBox = new JCheckBox();
|
|
|
|
+ diagnosticsCheckBox.setSelected(true);
|
|
|
|
+ diagnosticsCheckBox.setBounds(320, 60, 25, 20);
|
|
|
|
+ parameterPanel.add(diagnosticsCheckBox);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ NumberFormat format = NumberFormat.getIntegerInstance();
|
|
|
|
+ format.setGroupingUsed(false);
|
|
|
|
+ format.setParseIntegerOnly(true);
|
|
|
|
+ NumberFormatter integerFormatter = new NumberFormatter(format);
|
|
|
|
+ integerFormatter.setMinimum(0);
|
|
|
|
+ integerFormatter.setCommitsOnValidEdit(true);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ JFormattedTextField swarmSizeTextField = new JFormattedTextField(integerFormatter);
|
|
|
|
+ swarmSizeTextField.setValue(swarmSize);
|
|
|
|
+ swarmSizeTextField.setToolTipText("Only positive Integer.");
|
|
|
|
+ swarmSizeTextField.addPropertyChangeListener(propertyChange -> swarmSize = Integer.parseInt(swarmSizeTextField.getValue().toString()));
|
|
|
|
+ swarmSizeTextField.setBounds(125, 60, 50, 20);
|
|
|
|
+ parameterPanel.add(swarmSizeTextField);
|
|
|
|
+
|
|
|
|
+ JFormattedTextField maxIterTextField = new JFormattedTextField(integerFormatter);
|
|
|
|
+ maxIterTextField.setValue(maxIterations);
|
|
|
|
+ maxIterTextField.setToolTipText("Only positive Integer.");
|
|
|
|
+ maxIterTextField.addPropertyChangeListener(propertyChange -> maxIterations = Integer.parseInt(maxIterTextField.getValue().toString()));
|
|
|
|
+ maxIterTextField.setBounds(125, 85, 50, 20);
|
|
|
|
+ parameterPanel.add(maxIterTextField);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
|
|
|
|
+ doubleFormat.setMinimumFractionDigits(1);
|
|
|
|
+ doubleFormat.setMaximumFractionDigits(3);
|
|
|
|
+ doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ NumberFormatter limitFormatter = new NumberFormatter(doubleFormat);
|
|
|
|
+ limitFormatter.setMinimum(0.0);
|
|
|
|
+ limitFormatter.setMaximum(1.0);
|
|
|
|
+
|
|
|
|
+ JFormattedTextField limitTextField = new JFormattedTextField(limitFormatter);
|
|
|
|
+ limitTextField.setValue(limit);
|
|
|
|
+ limitTextField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
|
|
|
|
+ limitTextField.addPropertyChangeListener(propertyChange -> limit = Double.parseDouble(limitTextField.getValue().toString()));
|
|
|
|
+ limitTextField.setBounds(125, 110, 50, 20);
|
|
|
|
+ parameterPanel.add(limitTextField);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ NumberFormatter dependencyFormatter = new NumberFormatter(doubleFormat);
|
|
|
|
+ dependencyFormatter.setMinimum(2.001);
|
|
|
|
+ dependencyFormatter.setMaximum(2.4);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ JFormattedTextField dependencyTextField = new JFormattedTextField(dependencyFormatter);
|
|
|
|
+ dependencyTextField.setValue(dependency);
|
|
|
|
+ dependencyTextField.setToolTipText("Only Double in range [2.001, 2.4] with DecimalSeperator Point('.').");
|
|
|
|
+ dependencyTextField.addPropertyChangeListener(propertyChange -> dependency = Double.parseDouble(dependencyTextField.getValue().toString()));
|
|
|
|
+ dependencyTextField.setBounds(125, 135, 50, 20);
|
|
|
|
+ parameterPanel.add(dependencyTextField);
|
|
|
|
+
|
|
|
|
+ return parameterPanel;
|
|
|
|
+ }
|
|
|
|
+ public JPanel createButtonPanel() {
|
|
|
|
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
|
|
|
+ JButton clearButton = new JButton("Clear Console");
|
|
|
|
+ clearButton.addActionListener(actionEvent -> clear());
|
|
|
|
+ buttonPanel.add(clearButton);
|
|
|
|
+ JButton plottButton = new JButton("Plott");
|
|
|
|
+ buttonPanel.add(plottButton);
|
|
|
|
+ JButton runButton = new JButton("Run");
|
|
|
|
+ runButton.addActionListener(actionEvent -> executePsoAlgoWithCurrentParameters());
|
|
|
|
+ buttonPanel.add(runButton);
|
|
|
|
+ return buttonPanel;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void printParameter() {
|
|
|
|
+ println("SwarmSize:" + swarmSize + ", MaxIter:" + maxIterations + ", Limit:" + limit + ", Dependency:" + dependency);
|
|
|
|
+ }
|
|
|
|
+ @Override
|
|
|
|
+ public JPanel getAlgorithmPanel() {
|
|
|
|
+ return content;
|
|
|
|
+ }
|
|
|
|
+ @Override
|
|
|
|
+ public void setController(Control control) {
|
|
|
|
+ this.control = control;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ private void clear() {
|
|
|
|
+ textArea.setText("");
|
|
|
|
+ }
|
|
|
|
+ private void print(String message) {
|
|
|
|
+ textArea.append(message);
|
|
|
|
+ }
|
|
|
|
+ private void println(String message) {
|
|
|
|
+ textArea.append(message + "\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private void executePsoAlgoWithCurrentParameters() {
|
|
|
|
+ println("SwarmSize:" + swarmSize + ", MaxIter:" + maxIterations + ", Limit:" + limit + ", Dependency:" + dependency);
|
|
|
|
+ extractPosition(control.getModel());
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ for (int iteration = 0; iteration < maxIterations ; iteration++) {
|
|
|
|
+ for (int i = 0; i < swarmSize; i++) {
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ private List<Boolean> extractPosition(Model model) {
|
|
|
|
+ println("Start extracting");
|
|
|
|
+ List<Boolean> position = new ArrayList<Boolean>();
|
|
|
|
+ HashMap<Integer, AccessWrapper> access= new HashMap<Integer, AccessWrapper>();
|
|
|
|
+ rollOutNodes(model.getObjectsOnCanvas(), position, access, model.getCurIteration());
|
|
|
|
+ println("[" + position.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]");
|
|
|
|
+ ListIterator<Boolean> i = position.listIterator();
|
|
|
|
+ while(i.hasNext()) {
|
|
|
|
+ boolean actual = i.next();
|
|
|
|
+ double randomDouble = Math.random();
|
|
|
|
+ if (randomDouble < limit) {
|
|
|
|
+ i.set(!actual);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ println("[" + position.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]");
|
|
|
|
+ setState(position, access);
|
|
|
|
+ updateVisual();
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ private void updateVisual() {
|
|
|
|
+ control.calculateStateForCurrentTimeStep();
|
|
|
|
+ control.updateCanvas();
|
|
|
|
+ }
|
|
|
|
+ private void rollOutNodes(List<AbstractCpsObject> nodes, List<Boolean> positionToInit, HashMap<Integer, AccessWrapper> access, int timeStep) {
|
|
|
|
+ for(AbstractCpsObject aCps : nodes) {
|
|
|
|
+ if (aCps instanceof HolonObject) {
|
|
|
|
+ for (HolonElement hE : ((HolonObject) aCps).getElements()) {
|
|
|
|
+ positionToInit.add(hE.isActive());
|
|
|
|
+ access.put(positionToInit.size() - 1 , new AccessWrapper(hE));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (aCps instanceof HolonSwitch) {
|
|
|
|
+ HolonSwitch sw = (HolonSwitch) aCps;
|
|
|
|
+ positionToInit.add(sw.getState(timeStep));
|
|
|
|
+ access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
|
|
|
|
+ }
|
|
|
|
+ else if(aCps instanceof CpsUpperNode) {
|
|
|
|
+ rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit, access ,timeStep );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ private void setState(List<Boolean> position, HashMap<Integer, AccessWrapper> access) {
|
|
|
|
+ for(int i = 0;i<position.size();i++) {
|
|
|
|
+ access.get(i).setState(position.get(i));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public class AccessWrapper {
|
|
|
|
+ public static final int HOLONELEMENT = 0;
|
|
|
|
+ public static final int SWITCH = 1;
|
|
|
|
+ private int type;
|
|
|
|
+ private HolonSwitch hSwitch;
|
|
|
|
+ private HolonElement hElement;
|
|
|
|
+ public AccessWrapper(HolonSwitch hSwitch){
|
|
|
|
+ type = SWITCH;
|
|
|
|
+ this.hSwitch = hSwitch;
|
|
|
|
+ }
|
|
|
|
+ public AccessWrapper(HolonElement hElement){
|
|
|
|
+ type = HOLONELEMENT;
|
|
|
|
+ this.hElement = hElement;
|
|
|
|
+ }
|
|
|
|
+ public void setState(boolean state) {
|
|
|
|
+ if(type == HOLONELEMENT) {
|
|
|
|
+ hElement.setActive(state);
|
|
|
|
+ }else{
|
|
|
|
+ hSwitch.setManualMode(true);
|
|
|
|
+ hSwitch.setManualState(state);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ public boolean getState(int timeStep) {
|
|
|
|
+ return (type == HOLONELEMENT)?hElement.isActive():hSwitch.getState(timeStep);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|