Browse Source

Begin of PSO Implementation.

Tom Troppmann 5 years ago
parent
commit
0c93b32527

+ 1 - 0
src/exampleAlgorithms/ExampleFitnessFunction.java

@@ -28,6 +28,7 @@ public class ExampleFitnessFunction implements Algorithm {
 //	      newFrame.setContentPane(instance.getAlgorithmPanel());
 //	      newFrame.pack();
 //	      newFrame.setVisible(true);
+//		  newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 //	}
 	public ExampleFitnessFunction(){
 		content.setLayout(new BorderLayout());

+ 320 - 0
src/exampleAlgorithms/PSOAlgotihm.java

@@ -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 {
+	//Parameter for Algo with default Values:
+	private int swarmSize = 20; 
+	private int maxIterations = 100; 
+	private double limit = 1.0; 
+	private double dependency = 2.01; 
+	
+	
+	//Gui Part:
+	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);
+		
+		//Integer formatter
+		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);
+
+		//Double Format:
+		NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
+		doubleFormat.setMinimumFractionDigits(1);
+		doubleFormat.setMaximumFractionDigits(3);
+		doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
+
+		//Limit Formatter:
+		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);
+		
+		//Limit Formatter:
+		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");
+	}
+	
+	//Algo Part:
+	private void executePsoAlgoWithCurrentParameters() {
+		println("SwarmSize:" + swarmSize + ", MaxIter:" + maxIterations + ", Limit:" + limit + ", Dependency:" + dependency);//maybe local parameter to not get override by runnign
+		extractPosition(control.getModel());
+//		initSwarm(startPos);
+//		runFunction(model, control);
+//		evaluate();
+		
+		for (int iteration = 0; iteration < maxIterations ; iteration++) {
+			for (int i = 0; i < swarmSize; i++) {
+//				Particle temp = swarm.getSwarm().get(i);
+				
+				// Binary PSO 2 (S. Lee)
+				// Update Velocity
+//				temp.setVelocityAdv(updateNewVelAdv(temp.getVelocityAdv(), temp.getPositionAdv(),
+//						temp.getBestLocalPosAdv(), iterations));
+				// Update Position
+//				temp.setPositionAdv(updateNewPosAdv(temp.getVelocityAdv(), temp.getPositionAdv()));
+				// Mutation Position
+//				temp.setPositionAdv(mutatePos(temp.getPositionAdv()));
+				// Decode Position
+//				temp.setPositionAdv(decodePos(temp.getPositionAdv()));
+			}
+//			plotSwarm();
+//			runFunction(model, control);
+//			evaluate();
+		}
+	}
+	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{//is switch
+				hSwitch.setManualMode(true);
+				hSwitch.setManualState(state);
+			}
+				
+		}
+		public boolean getState(int timeStep) {
+			return (type == HOLONELEMENT)?hElement.isActive():hSwitch.getState(timeStep);
+		}
+	}
+}

+ 2 - 0
src/exampleAlgorithms/RandomSwitch.java

@@ -7,6 +7,7 @@ import java.util.Hashtable;
 import javax.swing.BorderFactory;
 import javax.swing.BoxLayout;
 import javax.swing.JButton;
+import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JSlider;
@@ -28,6 +29,7 @@ public class RandomSwitch implements Algorithm {
 //        newFrame.setContentPane(instance.getAlgorithmPanel());
 //        newFrame.pack();
 //        newFrame.setVisible(true);
+//	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 //    }
 	
 	public RandomSwitch(){