Rolf Egert 4 년 전
부모
커밋
8a06880572

+ 1 - 0
plott.txt

@@ -0,0 +1 @@
+

+ 4 - 4
src/Connection/ConnectHandheld.java

@@ -22,7 +22,7 @@ import javax.swing.JSplitPane;
 import javax.swing.JTextArea;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonObject;
@@ -32,7 +32,7 @@ import Connection.socket.Server;
 import ui.controller.Control;
 import ui.view.Console;
 
-public class ConnectHandheld implements Algorithm{
+public class ConnectHandheld implements AddOn{
 	
 	//Holeg
 	Control control;
@@ -59,7 +59,7 @@ public class ConnectHandheld implements Algorithm{
 	{
 	      JFrame newFrame = new JFrame("exampleWindow");
 	      ConnectHandheld instance = new ConnectHandheld();
-	      newFrame.setContentPane(instance.getAlgorithmPanel());
+	      newFrame.setContentPane(instance.getPanel());
 	      newFrame.pack();
 	      newFrame.setVisible(true);
 	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -164,7 +164,7 @@ public class ConnectHandheld implements Algorithm{
 	
 
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 

+ 4 - 4
src/Connection/ConnectPhysical.java

@@ -31,7 +31,7 @@ import javax.swing.JSplitPane;
 import javax.swing.JTextArea;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -44,7 +44,7 @@ import ui.view.Console;
  * @author tom
  *
  */
-public class ConnectPhysical implements Algorithm{
+public class ConnectPhysical implements AddOn{
 	//Holeg
 	private Control  control;
 	
@@ -113,7 +113,7 @@ public class ConnectPhysical implements Algorithm{
 	{
 	      JFrame newFrame = new JFrame("exampleWindow");
 	      ConnectPhysical instance = new ConnectPhysical();
-	      newFrame.setContentPane(instance.getAlgorithmPanel());
+	      newFrame.setContentPane(instance.getPanel());
 	      newFrame.pack();
 	      newFrame.setVisible(true);
 	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -502,7 +502,7 @@ public class ConnectPhysical implements Algorithm{
 	
 	
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 

+ 3 - 3
src/api/Algorithm.java → src/api/AddOn.java

@@ -5,10 +5,10 @@ import javax.swing.JPanel;
 import ui.controller.Control;
 
 /**
- * Interface for a Algorithm that is executed on the current timestep.
+ * Interface for a Standart Addon.
  * @author Tom Troppmann
  */
-public interface Algorithm  {
-	public JPanel getAlgorithmPanel();
+public interface AddOn  {
+	public JPanel getPanel();
 	public void setController(Control control);
 }

+ 640 - 0
src/api/AlgorithmFramework.java

@@ -0,0 +1,640 @@
+package api;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.image.BufferedImage;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.math.RoundingMode;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.stream.Collectors;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFileChooser;
+import javax.swing.JFormattedTextField;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.text.NumberFormatter;
+
+import classes.AbstractCpsObject;
+import classes.CpsUpperNode;
+import classes.HolonElement;
+import classes.HolonObject;
+import classes.HolonSwitch;
+import ui.controller.Control;
+import ui.model.DecoratedGroupNode;
+import ui.model.DecoratedState;
+import ui.model.Model;
+import ui.view.Console;
+
+public abstract class AlgorithmFramework implements AddOn{
+	//Algo
+	protected int rounds = 3;
+	
+	
+	
+	//Panel
+	private JPanel content = new JPanel();
+	protected Console console = new Console();
+	private JPanel borderPanel = new JPanel();
+	
+	
+	//Settings groupNode
+	private boolean useGroupNode = false;
+	private DecoratedGroupNode dGroupNode = null;
+	
+	
+	//access
+	private ArrayList<AccessWrapper> access;
+	LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
+	
+	
+	//time
+	private long startTime;
+	
+	
+	private RunProgressBar runProgressbar = new RunProgressBar();
+	
+	
+	
+	//concurrency
+	private Thread runThread = new Thread();
+	protected boolean cancel = false;
+
+	//holeg interaction
+	private Control  control;
+
+	
+	//printing
+	protected RunDataBase db;
+	private RunPrinter printer = new RunPrinter("plott.txt");
+
+
+
+	
+	
+	public AlgorithmFramework(){
+		content.setLayout(new BorderLayout());
+		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+				createOptionPanel() , console);
+		splitPane.setResizeWeight(0.0);
+		content.add(splitPane, BorderLayout.CENTER);
+		content.setPreferredSize(new Dimension(800,800));
+	}
+	
+	
+	
+	
+	
+	
+	private 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));
+		borderPanel.setLayout(new BoxLayout(borderPanel, BoxLayout.PAGE_AXIS));
+		addIntParameter("Rounds", rounds, intInput -> rounds = intInput, 1);
+		JScrollPane scrollPane = new JScrollPane(borderPanel);
+		scrollPane.setBounds(10, 0, 450, 292);
+		scrollPane.setBorder(BorderFactory.createEmptyBorder());
+		parameterPanel.add(scrollPane);	
+		
+		
+		
+		JButton selectGroupNodeButton = new JButton("Select GroupNode");
+		selectGroupNodeButton.setBounds(500, 0, 185, 30);
+		selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode());
+		parameterPanel.add(selectGroupNodeButton);	
+		JProgressBar progressBar = runProgressbar.getJProgressBar();
+		progressBar.setBounds(500, 35, 185, 20);
+		progressBar.setStringPainted(true);
+		parameterPanel.add(progressBar);
+		
+		return parameterPanel;
+	}
+	private JPanel createButtonPanel() {
+		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+		
+		JButton resetButton =  new JButton("Reset");
+		resetButton.setToolTipText("Resets the State to before the Algorithm has runed.");
+		resetButton.addActionListener(actionEvent -> reset());
+		buttonPanel.add(resetButton);
+		
+		JButton cancelButton =  new JButton("Cancel Run");
+		cancelButton.addActionListener(actionEvent -> cancel());
+		buttonPanel.add(cancelButton);
+		
+		JButton plottButton =  new JButton("Plott");
+		plottButton.addActionListener(actionEvent -> plott());
+		buttonPanel.add(plottButton);
+		
+		JButton fitnessButton =  new JButton("Fitness");
+		fitnessButton.setToolTipText("Fitness for the current state.");
+		fitnessButton.addActionListener(actionEvent -> fitness());
+		buttonPanel.add(fitnessButton);
+		
+		JButton runButton =  new JButton("Run");
+		runButton.addActionListener(actionEvent -> {
+			Runnable task = () -> run();
+			runThread = new Thread(task);
+			runThread.start();
+		});
+		buttonPanel.add(runButton);
+		
+		
+		
+		return buttonPanel;
+	}
+	
+	
+	
+	//ParameterImports
+	
+	//int
+	protected void addIntParameter(String parameterName, int parameterValue, IntConsumer setter) {
+		this.addIntParameter(parameterName, parameterValue, setter, Integer.MIN_VALUE, Integer.MAX_VALUE);
+	}
+	
+	protected void addIntParameter(String parameterName, int parameterValue, IntConsumer setter, int parameterMinValue) {
+		this.addIntParameter(parameterName, parameterValue, setter, parameterMinValue, Integer.MAX_VALUE);
+	}
+	
+	protected void addIntParameter(String parameterName, int parameterValue, IntConsumer setter, int parameterMinValue, int parameterMaxValue) {
+		JPanel singleParameterPanel = new JPanel();
+		singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
+		singleParameterPanel.setAlignmentX(0.0f);
+		singleParameterPanel.add(new JLabel(parameterName + ": "));
+		singleParameterPanel.add(Box.createHorizontalGlue());
+		NumberFormat format = NumberFormat.getIntegerInstance();
+		format.setGroupingUsed(false);
+		format.setParseIntegerOnly(true);
+		NumberFormatter integerFormatter = new NumberFormatter(format);
+		integerFormatter.setMinimum(parameterMinValue);
+		integerFormatter.setMaximum(parameterMaxValue);
+		integerFormatter.setCommitsOnValidEdit(true);
+		JFormattedTextField singleParameterTextField = new  JFormattedTextField(integerFormatter);
+		singleParameterTextField.setValue(parameterValue);
+		String minValue = (parameterMinValue == Integer.MIN_VALUE)?"Integer.MIN_VALUE":String.valueOf(parameterMinValue);
+		String maxValue = (parameterMaxValue == Integer.MAX_VALUE)?"Integer.MAX_VALUE":String.valueOf(parameterMaxValue);
+		singleParameterTextField.setToolTipText("Only integer \u2208 [" + minValue + "," + maxValue + "]");
+		singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(Integer.parseInt(singleParameterTextField.getValue().toString())));
+		singleParameterTextField.setMaximumSize(new Dimension(200, 30));
+		singleParameterTextField.setPreferredSize(new Dimension(200, 30));
+		singleParameterPanel.add(singleParameterTextField);
+		borderPanel.add(singleParameterPanel);
+	}
+	
+	
+	//double
+	protected void addDoubleParameter(String parameterName, double parameterValue, DoubleConsumer setter) {
+		this.addDoubleParameter(parameterName, parameterValue, setter, Double.MIN_VALUE, Double.MAX_VALUE);
+	}
+	
+	
+	protected void addDoubleParameter(String parameterName, double parameterValue, DoubleConsumer setter, double parameterMinValue) {
+		this.addDoubleParameter(parameterName, parameterValue, setter, parameterMinValue, Double.MAX_VALUE);
+	}
+	
+	
+	protected void addDoubleParameter(String parameterName, double parameterValue, DoubleConsumer setter, double parameterMinValue, double parameterMaxValue) {
+		JPanel singleParameterPanel = new JPanel();
+		singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
+		singleParameterPanel.setAlignmentX(0.0f);
+		singleParameterPanel.add(new JLabel(parameterName + ": "));
+		singleParameterPanel.add(Box.createHorizontalGlue());
+		NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
+		doubleFormat.setMinimumFractionDigits(1);
+		doubleFormat.setMaximumFractionDigits(10);
+		doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
+		NumberFormatter doubleFormatter = new NumberFormatter(doubleFormat);
+		doubleFormatter.setMinimum(parameterMinValue);
+		doubleFormatter.setMaximum(parameterMaxValue);
+		JFormattedTextField singleParameterTextField = new  JFormattedTextField(doubleFormatter);
+		singleParameterTextField.setValue(parameterValue);
+		String minValue = (parameterMinValue == Double.MIN_VALUE)?"Double.MIN_VALUE":String.valueOf(parameterMinValue);
+		String maxValue = (parameterMaxValue == Double.MAX_VALUE)?"Double.MAX_VALUE":String.valueOf(parameterMaxValue);
+		singleParameterTextField.setToolTipText("Only double \u2208 [" + minValue + "," + maxValue + "]");
+		singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(Double.parseDouble(singleParameterTextField.getValue().toString())));
+		singleParameterTextField.setMaximumSize(new Dimension(200, 30));
+		singleParameterTextField.setPreferredSize(new Dimension(200, 30));
+		singleParameterPanel.add(singleParameterTextField);
+		borderPanel.add(singleParameterPanel);
+	}
+	//boolean
+	protected void addBooleanParameter(String parameterName, boolean parameterValue, Consumer<Boolean> setter){
+		JPanel singleParameterPanel = new JPanel();
+		singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
+		singleParameterPanel.setAlignmentX(0.0f);
+		singleParameterPanel.add(new JLabel(parameterName + ": "));
+		singleParameterPanel.add(Box.createHorizontalGlue());
+		JCheckBox useGroupNodeCheckBox = new JCheckBox();
+		useGroupNodeCheckBox.setSelected(parameterValue);
+		useGroupNodeCheckBox.addActionListener(actionEvent -> setter.accept(useGroupNodeCheckBox.isSelected()));
+		singleParameterPanel.add(useGroupNodeCheckBox);
+		borderPanel.add(singleParameterPanel);
+	}
+	
+
+	private void startTimer(){
+		startTime = System.currentTimeMillis();
+	}
+	private void printElapsedTime(){
+		long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
+		console.println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds);
+	}
+	
+	private void plott() {
+		if(db!=null) {
+			console.println("Plott..");
+			printer.print("");
+		}else {
+			console.println("No run inistialized.");
+		}
+	}
+	
+	
+	private void cancel() {
+		if(runThread.isAlive()) {
+			console.println("Cancel run.");
+			cancel = true;
+			runProgressbar.stop();
+		} else {
+			console.println("Nothing to cancel.");
+		}
+	}
+	
+	
+	private void fitness() {
+		if(runThread.isAlive()) {
+			console.println("Run have to be cancelled First.");
+			return;
+		}
+		double currentFitness = evaluatePosition(extractPositionAndAccess());
+		resetChain.removeLast();
+		console.println("Actual Fitnessvalue: " + currentFitness);
+	}
+	
+	
+	private void selectGroupNode() {
+		Object[] possibilities = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().values().stream().map(aCps -> new Handle<DecoratedGroupNode>(aCps)).toArray();
+		@SuppressWarnings("unchecked")
+		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, "");
+		if(selected != null) {
+			console.println("Selected: " + selected);
+			dGroupNode = selected.object;
+		}
+	}
+	
+	protected double evaluatePosition(List<Boolean> positionToEvaluate) {
+		runProgressbar.step();
+		
+		setState(positionToEvaluate);
+		control.calculateStateOnlyForCurrentTimeStep();
+		DecoratedState actualstate = control.getSimManager().getActualDecorState();
+		return evaluateState(actualstate);
+	}
+
+	protected abstract double evaluateState(DecoratedState actualstate);
+
+	
+	private void run() {
+		cancel = false;
+		control.guiDisable(true);
+		executeAlgoWithParameter();
+		updateVisual();
+		control.guiDisable(false);
+	}
+	
+	private void executeAlgoWithParameter(){
+		runProgressbar.start();
+		int actualIteration = control.getModel().getCurIteration();
+		console.println("TimeStep:" + actualIteration);
+		startTimer();
+		Individual runBest = new Individual();
+		runBest.fitness = Double.MAX_VALUE;
+		db = new RunDataBase();
+		for(int r = 0; r < rounds; r++)
+		{		
+			Individual  roundBest = executeAlgo();
+			if(cancel)return;
+			resetState();
+			if(roundBest.fitness < runBest.fitness) runBest = roundBest;
+		}
+		printElapsedTime();
+		
+		setState(runBest.position);
+		
+		updateVisual();
+		console.println("AlgoResult:" + runBest.fitness);
+		runProgressbar.stop();
+	}
+	
+	
+	protected abstract Individual executeAlgo();
+
+
+
+
+
+
+	private void reset() {
+		if(runThread.isAlive()) {
+			console.println("Run have to be cancelled First.");
+			return;
+		}
+		if(!resetChain.isEmpty()) {
+			console.println("Resetting..");
+			setState(resetChain.getFirst());
+			resetChain.clear();
+			control.resetSimulation();
+			control.setCurIteration(0);
+			updateVisual();
+		}else {
+			console.println("No run inistialized.");
+		}
+	}
+
+
+	/**
+	 * To let the User See the current state without touching the Canvas.
+	 */
+	private void updateVisual() {
+		control.calculateStateAndVisualForCurrentTimeStep();
+	}
+	/**
+	 * Sets the Model back to its original State before the LAST run.
+	 */
+	private void resetState() {
+		setState(resetChain.getLast());
+	}
+
+
+	/**
+	 * Sets the State out of the given position for calculation or to show the user.
+	 * @param position
+	 */
+	private void setState(List<Boolean> position) {
+		int i = 0;
+		for(Boolean bool: position) {
+			access.get(i++).setState(bool);
+		}
+}
+
+
+	/**
+	 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
+	 * Also initialize the Access Hashmap to swap faster positions.
+	 * @param model
+	 * @return
+	 */
+	protected List<Boolean> extractPositionAndAccess() {
+		Model model = control.getModel();
+		access= new ArrayList<AccessWrapper>();
+		List<Boolean> initialState = new ArrayList<Boolean>();
+		rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getCurIteration());			
+		resetChain.add(initialState); 
+		return initialState;
+	}
+	
+	/**
+	 * Method to extract the Informations recursively out of the Model.
+	 * @param nodes
+	 * @param positionToInit
+	 * @param timeStep
+	 */
+	private void rollOutNodes(List<AbstractCpsObject> nodes, List<Boolean> positionToInit, int timeStep) {
+		for(AbstractCpsObject aCps : nodes) {
+			if (aCps instanceof HolonObject) {
+				for (HolonElement hE : ((HolonObject) aCps).getElements()) {
+					positionToInit.add(hE.isActive());
+					access.add(new AccessWrapper(hE));
+				}
+			}
+			else if (aCps instanceof HolonSwitch) {
+				HolonSwitch sw = (HolonSwitch) aCps;
+				positionToInit.add(sw.getState(timeStep));
+				access.add(new AccessWrapper(sw));
+			}
+			else if(aCps instanceof CpsUpperNode) {
+				rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit ,timeStep );
+			}
+		}
+	}
+	
+	
+	
+	
+	
+	
+
+	
+	@Override
+	public JPanel getPanel() {
+		return content;
+	}
+
+	@Override
+	public void setController(Control control) {
+		this.control = control;
+	}
+	
+	
+	
+	private class RunProgressBar{
+		//progressbar
+		private JProgressBar progressBar = new JProgressBar();
+		private int count = 0;
+		private boolean isActive = false;
+		public void step() {
+			if(isActive) progressBar.setValue(count++);
+			progressBar.setMaximum(getProgressBarMaxCount());
+		}
+		public void start() {
+			isActive = true;
+			progressBar.setValue(0);
+		}
+		public void stop() {
+			isActive = false;
+		}
+		public JProgressBar getJProgressBar(){
+			return progressBar;
+		}
+	}
+	
+	protected abstract int getProgressBarMaxCount();
+	
+	
+	
+	
+	public class RunDataBase{
+		List<List<Double>> allRuns = new ArrayList<List<Double>>();
+		public void insertNewRun(List<Double> newRun){
+			allRuns.add(newRun);
+		}
+		
+	}
+	
+	
+	
+	public class RunPrinter{
+		//Fields
+		private JFileChooser fileChooser = new JFileChooser();
+		private boolean append = false;
+		//Constructor
+		public RunPrinter(String filename) {
+			this(filename, false);
+		}
+		
+		public RunPrinter(String filename,  boolean append){
+			this.append = append;
+			fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
+			setFilename(filename);
+		}
+		//public methods
+		public void enableAppend(boolean enable) {
+			append = enable;
+		}
+		public void setFilename(String filename) {
+			fileChooser.setSelectedFile(new File(filename));
+		}
+		public void print(String info) {
+			File file = fileChooser.getSelectedFile();
+			try {
+				file.createNewFile();
+				BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
+					    new FileOutputStream(file, append), "UTF-8"));
+				printToStream(out, info);
+				out.close();
+			} catch (IOException e) {
+				System.out.println(e.getMessage());
+			}
+		}
+		//private methods
+		private void printToStream(BufferedWriter out, String info) throws IOException {	
+			out.write(info);
+			out.newLine();
+			if(db != null)
+			out.write(db.allRuns.stream().map(list -> list.stream().map(Object::toString).collect(Collectors.joining(","))).collect(Collectors.joining(System.lineSeparator())));
+		}
+	}
+		
+	
+	/**
+	 * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split the List.
+	 */
+	private 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);
+		}
+		public int getType() {
+			return type;
+		}
+	}
+	
+	
+	
+	
+	/**
+	* To create Random and maybe switch the random generation in the future.
+	*/
+	protected static class Random{
+		private static java.util.Random random = new java.util.Random();
+		/**
+		 * True or false
+		 * @return the random boolean.
+		 */
+		public static boolean nextBoolean(){
+			return random.nextBoolean();
+		}
+		/**
+		 * Between 0.0(inclusive) and 1.0 (exclusive)
+		 * @return the random double.
+		 */
+		public static double nextDouble() {
+			return random.nextDouble();
+		}
+		
+		/**
+		 * Random Int in Range [min;max[ with UniformDistirbution
+		 * @param min
+		 * @param max
+		 * @return
+		 */
+		public static int nextIntegerInRange(int min, int max) {
+			return min + random.nextInt(max - min);
+		}
+	}
+	
+	private   class  Handle<T>{
+		public T object;
+		Handle(T object){
+			this.object = object;
+		}
+		public String toString() {
+			return object.toString();
+		}
+	}
+	public class Individual {
+		public double fitness;
+		public  List<Boolean> position;
+		
+		public Individual(){};
+		/**
+		 *  Copy Constructor
+		 */
+		public Individual(Individual c){
+			position = c.position.stream().collect(Collectors.toList());
+			fitness = c.fitness;
+		}
+	}
+}

+ 684 - 0
src/api/AlgorithmFrameworkFlex.java

@@ -0,0 +1,684 @@
+package api;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.image.BufferedImage;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.math.RoundingMode;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.stream.Collectors;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFileChooser;
+import javax.swing.JFormattedTextField;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.text.NumberFormatter;
+
+import classes.AbstractCpsObject;
+import classes.CpsUpperNode;
+import classes.Flexibility;
+import classes.HolonElement;
+import classes.HolonObject;
+import classes.HolonSwitch;
+import ui.controller.Control;
+import ui.controller.FlexManager.FlexState;
+import ui.controller.FlexManager.FlexWrapper;
+import ui.model.DecoratedGroupNode;
+import ui.model.DecoratedState;
+import ui.model.Model;
+import ui.view.Console;
+
+public abstract class AlgorithmFrameworkFlex implements AddOn{
+	//Algo
+	protected int rounds = 3;
+	
+	
+	
+	//Panel
+	private JPanel content = new JPanel();
+	protected Console console = new Console();
+	private JPanel borderPanel = new JPanel();
+	
+	
+	//Settings groupNode
+	private boolean useGroupNode = false;
+	private DecoratedGroupNode dGroupNode = null;
+	
+	
+	//access
+	private ArrayList<AccessWrapper> access;
+	LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
+	
+	
+	//time
+	private long startTime;
+	
+	
+	private RunProgressBar runProgressbar = new RunProgressBar();
+	
+	
+	
+	//concurrency
+	private Thread runThread = new Thread();
+	protected boolean cancel = false;
+
+	//holeg interaction
+	private Control  control;
+
+	
+	//printing
+	protected RunDataBase db;
+	private RunPrinter printer = new RunPrinter("plott.txt");
+
+
+
+	
+	
+	public AlgorithmFrameworkFlex(){
+		content.setLayout(new BorderLayout());
+		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+				createOptionPanel() , console);
+		splitPane.setResizeWeight(0.0);
+		content.add(splitPane, BorderLayout.CENTER);
+		content.setPreferredSize(new Dimension(800,800));
+	}
+	
+	
+	
+	
+	
+	
+	private 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));
+		borderPanel.setLayout(new BoxLayout(borderPanel, BoxLayout.PAGE_AXIS));
+		addIntParameter("Rounds", rounds, intInput -> rounds = intInput, 1);
+		JScrollPane scrollPane = new JScrollPane(borderPanel);
+		scrollPane.setBounds(10, 0, 450, 292);
+		scrollPane.setBorder(BorderFactory.createEmptyBorder());
+		parameterPanel.add(scrollPane);	
+		
+		
+		
+		JButton selectGroupNodeButton = new JButton("Select GroupNode");
+		selectGroupNodeButton.setBounds(500, 0, 185, 30);
+		selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode());
+		parameterPanel.add(selectGroupNodeButton);	
+		JProgressBar progressBar = runProgressbar.getJProgressBar();
+		progressBar.setBounds(500, 35, 185, 20);
+		progressBar.setStringPainted(true);
+		parameterPanel.add(progressBar);
+		
+		return parameterPanel;
+	}
+	private JPanel createButtonPanel() {
+		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+		
+		JButton resetButton =  new JButton("Reset");
+		resetButton.setToolTipText("Resets the State to before the Algorithm has runed.");
+		resetButton.addActionListener(actionEvent -> reset());
+		buttonPanel.add(resetButton);
+		
+		JButton cancelButton =  new JButton("Cancel Run");
+		cancelButton.addActionListener(actionEvent -> cancel());
+		buttonPanel.add(cancelButton);
+		
+		JButton plottButton =  new JButton("Plott");
+		plottButton.addActionListener(actionEvent -> plott());
+		buttonPanel.add(plottButton);
+		
+		JButton fitnessButton =  new JButton("Fitness");
+		fitnessButton.setToolTipText("Fitness for the current state.");
+		fitnessButton.addActionListener(actionEvent -> fitness());
+		buttonPanel.add(fitnessButton);
+		
+		JButton runButton =  new JButton("Run");
+		runButton.addActionListener(actionEvent -> {
+			Runnable task = () -> run();
+			runThread = new Thread(task);
+			runThread.start();
+		});
+		buttonPanel.add(runButton);
+		
+		
+		
+		return buttonPanel;
+	}
+	
+	
+	
+	//ParameterImports
+	
+	//int
+	protected void addIntParameter(String parameterName, int parameterValue, IntConsumer setter) {
+		this.addIntParameter(parameterName, parameterValue, setter, Integer.MIN_VALUE, Integer.MAX_VALUE);
+	}
+	
+	protected void addIntParameter(String parameterName, int parameterValue, IntConsumer setter, int parameterMinValue) {
+		this.addIntParameter(parameterName, parameterValue, setter, parameterMinValue, Integer.MAX_VALUE);
+	}
+	
+	protected void addIntParameter(String parameterName, int parameterValue, IntConsumer setter, int parameterMinValue, int parameterMaxValue) {
+		JPanel singleParameterPanel = new JPanel();
+		singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
+		singleParameterPanel.setAlignmentX(0.0f);
+		singleParameterPanel.add(new JLabel(parameterName + ": "));
+		singleParameterPanel.add(Box.createHorizontalGlue());
+		NumberFormat format = NumberFormat.getIntegerInstance();
+		format.setGroupingUsed(false);
+		format.setParseIntegerOnly(true);
+		NumberFormatter integerFormatter = new NumberFormatter(format);
+		integerFormatter.setMinimum(parameterMinValue);
+		integerFormatter.setMaximum(parameterMaxValue);
+		integerFormatter.setCommitsOnValidEdit(true);
+		JFormattedTextField singleParameterTextField = new  JFormattedTextField(integerFormatter);
+		singleParameterTextField.setValue(parameterValue);
+		String minValue = (parameterMinValue == Integer.MIN_VALUE)?"Integer.MIN_VALUE":String.valueOf(parameterMinValue);
+		String maxValue = (parameterMaxValue == Integer.MAX_VALUE)?"Integer.MAX_VALUE":String.valueOf(parameterMaxValue);
+		singleParameterTextField.setToolTipText("Only integer \u2208 [" + minValue + "," + maxValue + "]");
+		singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(Integer.parseInt(singleParameterTextField.getValue().toString())));
+		singleParameterTextField.setMaximumSize(new Dimension(200, 30));
+		singleParameterTextField.setPreferredSize(new Dimension(200, 30));
+		singleParameterPanel.add(singleParameterTextField);
+		borderPanel.add(singleParameterPanel);
+	}
+	
+	
+	//double
+	protected void addDoubleParameter(String parameterName, double parameterValue, DoubleConsumer setter) {
+		this.addDoubleParameter(parameterName, parameterValue, setter, Double.MIN_VALUE, Double.MAX_VALUE);
+	}
+	
+	
+	protected void addDoubleParameter(String parameterName, double parameterValue, DoubleConsumer setter, double parameterMinValue) {
+		this.addDoubleParameter(parameterName, parameterValue, setter, parameterMinValue, Double.MAX_VALUE);
+	}
+	
+	
+	protected void addDoubleParameter(String parameterName, double parameterValue, DoubleConsumer setter, double parameterMinValue, double parameterMaxValue) {
+		JPanel singleParameterPanel = new JPanel();
+		singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
+		singleParameterPanel.setAlignmentX(0.0f);
+		singleParameterPanel.add(new JLabel(parameterName + ": "));
+		singleParameterPanel.add(Box.createHorizontalGlue());
+		NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
+		doubleFormat.setMinimumFractionDigits(1);
+		doubleFormat.setMaximumFractionDigits(10);
+		doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
+		NumberFormatter doubleFormatter = new NumberFormatter(doubleFormat);
+		doubleFormatter.setMinimum(parameterMinValue);
+		doubleFormatter.setMaximum(parameterMaxValue);
+		JFormattedTextField singleParameterTextField = new  JFormattedTextField(doubleFormatter);
+		singleParameterTextField.setValue(parameterValue);
+		String minValue = (parameterMinValue == Double.MIN_VALUE)?"Double.MIN_VALUE":String.valueOf(parameterMinValue);
+		String maxValue = (parameterMaxValue == Double.MAX_VALUE)?"Double.MAX_VALUE":String.valueOf(parameterMaxValue);
+		singleParameterTextField.setToolTipText("Only double \u2208 [" + minValue + "," + maxValue + "]");
+		singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(Double.parseDouble(singleParameterTextField.getValue().toString())));
+		singleParameterTextField.setMaximumSize(new Dimension(200, 30));
+		singleParameterTextField.setPreferredSize(new Dimension(200, 30));
+		singleParameterPanel.add(singleParameterTextField);
+		borderPanel.add(singleParameterPanel);
+	}
+	//boolean
+	protected void addBooleanParameter(String parameterName, boolean parameterValue, Consumer<Boolean> setter){
+		JPanel singleParameterPanel = new JPanel();
+		singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
+		singleParameterPanel.setAlignmentX(0.0f);
+		singleParameterPanel.add(new JLabel(parameterName + ": "));
+		singleParameterPanel.add(Box.createHorizontalGlue());
+		JCheckBox useGroupNodeCheckBox = new JCheckBox();
+		useGroupNodeCheckBox.setSelected(parameterValue);
+		useGroupNodeCheckBox.addActionListener(actionEvent -> setter.accept(useGroupNodeCheckBox.isSelected()));
+		singleParameterPanel.add(useGroupNodeCheckBox);
+		borderPanel.add(singleParameterPanel);
+	}
+	
+
+	private void startTimer(){
+		startTime = System.currentTimeMillis();
+	}
+	private void printElapsedTime(){
+		long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
+		console.println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds);
+	}
+	
+	private void plott() {
+		if(db!=null) {
+			console.println("Plott..");
+			printer.print("");
+		}else {
+			console.println("No run inistialized.");
+		}
+	}
+	
+	
+	private void cancel() {
+		if(runThread.isAlive()) {
+			console.println("Cancel run.");
+			cancel = true;
+			runProgressbar.stop();
+		} else {
+			console.println("Nothing to cancel.");
+		}
+	}
+	
+	
+	private void fitness() {
+		if(runThread.isAlive()) {
+			console.println("Run have to be cancelled First.");
+			return;
+		}
+		double currentFitness = evaluatePosition(extractPositionAndAccess());
+		resetChain.removeLast();
+		console.println("Actual Fitnessvalue: " + currentFitness);
+	}
+	
+	
+	private void selectGroupNode() {
+		Object[] possibilities = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().values().stream().map(aCps -> new Handle<DecoratedGroupNode>(aCps)).toArray();
+		@SuppressWarnings("unchecked")
+		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, "");
+		if(selected != null) {
+			console.println("Selected: " + selected);
+			dGroupNode = selected.object;
+		}
+	}
+	
+	protected double evaluatePosition(List<Boolean> positionToEvaluate) {
+		runProgressbar.step();
+		control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration());
+		setState(positionToEvaluate);
+		control.calculateStateOnlyForCurrentTimeStep();
+		DecoratedState actualstate = control.getSimManager().getActualDecorState();
+		return evaluateState(actualstate);
+	}
+
+	protected abstract double evaluateState(DecoratedState actualstate);
+
+	
+	private void run() {
+		cancel = false;
+		control.guiDisable(true);
+		executeAlgoWithParameter();
+		updateVisual();
+		control.guiDisable(false);
+	}
+	
+	private void executeAlgoWithParameter(){
+		runProgressbar.start();
+		int actualIteration = control.getModel().getCurIteration();
+		console.println("TimeStep:" + actualIteration);
+		startTimer();
+		Individual runBest = new Individual();
+		runBest.fitness = Double.MAX_VALUE;
+		db = new RunDataBase();
+		for(int r = 0; r < rounds; r++)
+		{		
+			Individual  roundBest = executeAlgo();
+			if(cancel)return;
+			resetState();
+			if(roundBest.fitness < runBest.fitness) runBest = roundBest;
+		}
+		printElapsedTime();
+		control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration());
+		setState(runBest.position);
+		updateVisual();
+		console.println("AlgoResult:" + runBest.fitness);
+		runProgressbar.stop();
+	}
+	
+	
+	protected abstract Individual executeAlgo();
+
+
+
+
+
+
+	private void reset() {
+		if(runThread.isAlive()) {
+			console.println("Run have to be cancelled First.");
+			return;
+		}
+		if(!resetChain.isEmpty()) {
+			console.println("Resetting..");
+			setState(resetChain.getFirst());
+			resetChain.clear();
+			control.resetSimulation();
+			control.setCurIteration(0);
+			updateVisual();
+		}else {
+			console.println("No run inistialized.");
+		}
+	}
+
+
+	/**
+	 * To let the User See the current state without touching the Canvas.
+	 */
+	private void updateVisual() {
+		control.calculateStateAndVisualForCurrentTimeStep();
+	}
+	/**
+	 * Sets the Model back to its original State before the LAST run.
+	 */
+	private void resetState() {
+		control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration());
+		setState(resetChain.getLast());
+	}
+
+
+	/**
+	 * Sets the State out of the given position for calculation or to show the user.
+	 * @param position
+	 */
+	private void setState(List<Boolean> position) {
+		int i = 0;
+		for(Boolean bool: position) {
+			access.get(i++).setState(bool);
+		}
+		
+}
+
+
+	/**
+	 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
+	 * Also initialize the Access Hashmap to swap faster positions.
+	 * @param model
+	 * @return
+	 */
+	protected List<Boolean> extractPositionAndAccess() {
+		Model model = control.getModel();
+		access= new ArrayList<AccessWrapper>();
+		List<Boolean> initialState = new ArrayList<Boolean>();
+		rollOutNodes((useGroupNode && (dGroupNode != null))? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getCurIteration());			
+		resetChain.add(initialState);
+		for(FlexWrapper flex :control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.OFFERED)){
+			access.add(new AccessWrapper(flex.getFlex()));
+			initialState.add(false);
+		}
+		console.println(access.stream().map(Object::toString).collect(Collectors.joining(", ")));
+		return initialState;
+	}
+	
+	/**
+	 * Method to extract the Informations recursively out of the Model.
+	 * @param nodes
+	 * @param positionToInit
+	 * @param timeStep
+	 */
+	private void rollOutNodes(List<AbstractCpsObject> nodes, List<Boolean> positionToInit, int timeStep) {
+		for(AbstractCpsObject aCps : nodes) {
+			if (aCps instanceof HolonObject) {
+				for (HolonElement hE : ((HolonObject) aCps).getElements()) {
+					positionToInit.add(hE.isActive());
+					access.add(new AccessWrapper(hE));
+				}
+			}
+			else if (aCps instanceof HolonSwitch) {
+				HolonSwitch sw = (HolonSwitch) aCps;
+				positionToInit.add(sw.getState(timeStep));
+				access.add(new AccessWrapper(sw));
+			}
+			else if(aCps instanceof CpsUpperNode) {
+				rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit ,timeStep );
+			}
+		}
+	}
+	
+	
+	
+	
+	
+	
+
+	
+	@Override
+	public JPanel getPanel() {
+		return content;
+	}
+
+	@Override
+	public void setController(Control control) {
+		this.control = control;
+	}
+	
+	
+	
+	private class RunProgressBar{
+		//progressbar
+		private JProgressBar progressBar = new JProgressBar();
+		private int count = 0;
+		private boolean isActive = false;
+		public void step() {
+			if(isActive) progressBar.setValue(count++);
+			progressBar.setMaximum(getProgressBarMaxCount());
+		}
+		public void start() {
+			isActive = true;
+			progressBar.setValue(0);
+		}
+		public void stop() {
+			isActive = false;
+		}
+		public JProgressBar getJProgressBar(){
+			return progressBar;
+		}
+	}
+	
+	protected abstract int getProgressBarMaxCount();
+	
+	
+	
+	
+	public class RunDataBase{
+		List<List<Double>> allRuns = new ArrayList<List<Double>>();
+		public void insertNewRun(List<Double> newRun){
+			allRuns.add(newRun);
+		}
+		
+	}
+	
+	
+	
+	public class RunPrinter{
+		//Fields
+		private JFileChooser fileChooser = new JFileChooser();
+		private boolean append = false;
+		//Constructor
+		public RunPrinter(String filename) {
+			this(filename, false);
+		}
+		
+		public RunPrinter(String filename,  boolean append){
+			this.append = append;
+			fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
+			setFilename(filename);
+		}
+		//public methods
+		public void enableAppend(boolean enable) {
+			append = enable;
+		}
+		public void setFilename(String filename) {
+			fileChooser.setSelectedFile(new File(filename));
+		}
+		public void print(String info) {
+			File file = fileChooser.getSelectedFile();
+			try {
+				file.createNewFile();
+				BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
+					    new FileOutputStream(file, append), "UTF-8"));
+				printToStream(out, info);
+				out.close();
+			} catch (IOException e) {
+				System.out.println(e.getMessage());
+			}
+		}
+		//private methods
+		private void printToStream(BufferedWriter out, String info) throws IOException {	
+			out.write(info);
+			out.newLine();
+			if(db != null)
+			out.write(db.allRuns.stream().map(list -> list.stream().map(Object::toString).collect(Collectors.joining(","))).collect(Collectors.joining(System.lineSeparator())));
+		}
+	}
+		
+	
+	/**
+	 * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split the List.
+	 */
+	private class AccessWrapper {
+		public static final int HOLONELEMENT = 0;
+		public static final int SWITCH = 1;
+		public static final int FLEXIBILITY = 2;
+		private int type;
+		private HolonSwitch hSwitch;
+		private HolonElement hElement;
+		private Flexibility flex;
+		public AccessWrapper(HolonSwitch hSwitch){
+			type = SWITCH;
+			this.hSwitch = hSwitch;
+		}
+		public AccessWrapper(HolonElement hElement){
+			type = HOLONELEMENT;
+			this.hElement = hElement;
+		}
+		
+		public AccessWrapper(Flexibility flex){
+			type = FLEXIBILITY;
+			this.flex = flex;
+		}
+		
+		public void setState(boolean state) {
+			switch(type) {
+				case HOLONELEMENT:
+					hElement.setActive(state);
+					break;
+				case SWITCH:
+					hSwitch.setManualMode(true);
+					hSwitch.setManualState(state);
+					break;
+				case FLEXIBILITY:
+					
+					if(state) {
+						console.println("Flex True");
+						if(flex == null) console.println("flex == null");
+						if(control.getSimManager() == null) console.println("control.getSimManager() == null");
+						if(control.getSimManager().getActualFlexManager() == null) console.println("control.getSimManager().getActualFlexManager() == null");
+						control.getSimManager().getActualFlexManager().orderFlex(flex);
+					}else {
+						console.println("Flex false");
+					}
+					break;
+				default:
+				
+			}
+		}
+		
+		public String typeString() {
+			switch(type) {
+				case HOLONELEMENT:
+					return "HOLONELEMENT";
+				case SWITCH:
+					return "SWITCH";
+				case FLEXIBILITY:
+					return "FLEXIBILITY";
+				default:
+					return "unknown";
+			}
+		}
+		
+		public String toString() {
+			return "[" +  typeString() + "]";
+		}
+	}
+	
+	
+	
+	
+	/**
+	* To create Random and maybe switch the random generation in the future.
+	*/
+	protected static class Random{
+		private static java.util.Random random = new java.util.Random();
+		/**
+		 * True or false
+		 * @return the random boolean.
+		 */
+		public static boolean nextBoolean(){
+			return random.nextBoolean();
+		}
+		/**
+		 * Between 0.0(inclusive) and 1.0 (exclusive)
+		 * @return the random double.
+		 */
+		public static double nextDouble() {
+			return random.nextDouble();
+		}
+		
+		/**
+		 * Random Int in Range [min;max[ with UniformDistirbution
+		 * @param min
+		 * @param max
+		 * @return
+		 */
+		public static int nextIntegerInRange(int min, int max) {
+			return min + random.nextInt(max - min);
+		}
+	}
+	
+	private   class  Handle<T>{
+		public T object;
+		Handle(T object){
+			this.object = object;
+		}
+		public String toString() {
+			return object.toString();
+		}
+	}
+	public class Individual {
+		public double fitness;
+		public  List<Boolean> position;
+		
+		public Individual(){};
+		/**
+		 *  Copy Constructor
+		 */
+		public Individual(Individual c){
+			position = c.position.stream().collect(Collectors.toList());
+			fitness = c.fitness;
+		}
+	}
+}

+ 5 - 8
src/exampleAlgorithms/AcoAlgorithm.java

@@ -36,7 +36,7 @@ import javax.swing.JSplitPane;
 import javax.swing.JTextArea;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -50,7 +50,7 @@ import ui.model.Model;
 import ui.view.Console;
 import ui.model.DecoratedHolonObject.HolonObjectState;
 
-public class AcoAlgorithm implements Algorithm {
+public class AcoAlgorithm implements AddOn {
 
 		//Parameter for Algo with default Values:
 		/**
@@ -110,7 +110,7 @@ public class AcoAlgorithm implements Algorithm {
 		{
 		      JFrame newFrame = new JFrame("exampleWindow");
 		      AcoAlgorithm instance = new AcoAlgorithm();
-		      newFrame.setContentPane(instance.getAlgorithmPanel());
+		      newFrame.setContentPane(instance.getPanel());
 		      newFrame.pack();
 		      newFrame.setVisible(true);
 		      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -368,7 +368,7 @@ public class AcoAlgorithm implements Algorithm {
 
 		
 		private void disableGuiInput(boolean bool) {
-			control.guiDiable(bool);
+			control.guiDisable(bool);
 		}
 		
 		
@@ -376,7 +376,7 @@ public class AcoAlgorithm implements Algorithm {
 		
 		
 		@Override
-		public JPanel getAlgorithmPanel() {
+		public JPanel getPanel() {
 			return content;
 		}
 		@Override
@@ -639,8 +639,6 @@ public class AcoAlgorithm implements Algorithm {
 		 */
 		private void updateVisual() {
 			control.calculateStateAndVisualForCurrentTimeStep();
-			//control.updateCanvas();
-			//control.getGui().triggerUpdateController(null);
 		}
 		/**
 		 * Sets the Model back to its original State before the LAST run.
@@ -717,7 +715,6 @@ public class AcoAlgorithm implements Algorithm {
 		 */
 		public class RunDataBase {
 			List<List<Double>> allRuns = new ArrayList<List<Double>>();
-
 			
 			
 			/**

+ 196 - 0
src/exampleAlgorithms/AcoAlgorithm2.java

@@ -0,0 +1,196 @@
+package exampleAlgorithms;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import api.AlgorithmFramework;
+import api.AlgorithmFrameworkFlex;
+import ui.model.DecoratedState;
+
+public class AcoAlgorithm2 extends AlgorithmFrameworkFlex{
+	
+	//Parameter for Algo with default Values:
+	/**
+	 * Should be even.
+	 */
+	private int popsize = 20;
+	private int maxGenerations = 200;
+	/**
+	 * The vaporization factor;
+	 */
+	private double p = 0.3;
+	private double convergenceFactorReset = 0.99;
+	private boolean moreInformation = false;
+	
+	
+	
+	public AcoAlgorithm2() {
+		super();
+		addIntParameter("Population", popsize, intValue -> popsize = intValue, 1);
+		addIntParameter("maxGenerations", maxGenerations, intValue -> maxGenerations = intValue, 1);
+		addDoubleParameter("Vaporization", p, doubleValue -> p = doubleValue, 0.0, 1.0);
+		addDoubleParameter("FactorReset", convergenceFactorReset, doubleValue -> convergenceFactorReset = doubleValue, 0.0, 1.0);
+		addBooleanParameter("moreInformation", moreInformation, booleanValue -> moreInformation = booleanValue);
+	}
+	
+	
+	
+	public static void main(String[] args)
+	{
+	      JFrame newFrame = new JFrame("exampleWindow");
+	      AcoAlgorithm2 instance = new AcoAlgorithm2();
+	      newFrame.setContentPane(instance.getPanel());
+	      newFrame.pack();
+	      newFrame.setVisible(true);
+	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+	}
+
+	
+	
+	
+	@Override
+	protected double evaluateState(DecoratedState actualstate) {
+		return Evaluation.getFitnessValueForState(actualstate);
+	}
+
+
+	@Override
+	protected int getProgressBarMaxCount() {
+		return rounds * popsize * maxGenerations;
+	}
+	
+	
+	/** 	
+	 * 	Algorithm 20 !! Fitness is better when smaller.: 
+	 *  PseudoCode:
+	 *  Best <- actual;
+	 *  pheromones = initPheromons();
+	 * 	for(maxGeneration times){
+	 * 		population = createSolutionsBiasedBy(pheromones);
+	 * 		for(each Individual i from population){
+	 * 			fitness <- evaluatePosition(i);
+	 * 			if(fitness < best.fitnessValue) Best <- i;
+	 * 		}
+	 * 		vaporizeIntensifiePheromons(pheromones);
+	 * 	}
+	 * @return 
+	 */
+	@Override
+	protected Individual executeAlgo() {
+		Individual best = new Individual();
+		best.position = extractPositionAndAccess();
+		if(moreInformation )console.println("Bit-Array_length: " + best.position.size());
+		best.fitness = evaluatePosition(best.position);
+		List<Double> runList = new ArrayList<Double>();
+		runList.add(best.fitness);
+		console.print("Start with: " + best.fitness);
+		if(moreInformation)console.println("");
+		int problemSize = best.position.size();
+		if(problemSize == 0) return best;
+		List<Double> pheromones = initPheromones(problemSize);
+		List<Individual> population = new ArrayList<Individual>();
+		if(moreInformation)console.println("Size To Test:" + population.size());
+		for(int generation = 0; generation< maxGenerations; generation++) {
+			population.clear();
+			population = constructSolutionsBiasedBy(pheromones);
+			if(moreInformation)console.println("Generation" + generation + " start with Fitness: " + best.fitness);
+			for(Individual i : population) {
+				i.fitness = evaluatePosition(i.position);
+				if(moreInformation)console.println("Fitness" + i.fitness);
+				if(i.fitness < best.fitness) best = i;	
+			}
+			runList.add(best.fitness);
+			if(moreInformation)console.println("________________");
+			vaporizeIntensifiePheromons(pheromones, best.position, problemSize);
+			double cf = calculateConvergenceFactor(pheromones, problemSize);
+			if(moreInformation)console.println("ConvergenceFactor = " + cf);
+			if(cf > this.convergenceFactorReset) {
+				pheromones = initPheromones(problemSize);
+			}
+			if(cancel)return null;
+		}
+		
+		
+		console.println("   End With:" + best.fitness);
+		db.insertNewRun(runList);
+		return best;
+		
+	}
+			
+			
+	/**
+	 * tj1 is the pheromon level in the j position
+	 * cf is the convergence factor cf e [0;1]
+	 * difference = | tj1 - tj0 | = | tj1 - (1 - tj1) |
+	 * 
+	 * 
+	 * 
+	 * @param pheromones
+	 * @return cf
+	 */
+	private double calculateConvergenceFactor(List<Double> pheromones,int problemSize) {
+		double sumOfDifference = pheromones.stream().map(tj1 -> Math.abs(tj1 - (1.0 - tj1))).reduce(0.0, Double::sum);
+		double cf = sumOfDifference / (double)problemSize;
+		return cf;
+	}
+	/**
+	 * pheromone <- (1-p) * pheromone;
+	 * if(best is true at this position) pheromone <- pheromone + p;
+	 * @param pheromones
+	 * @param position
+	 */
+	private void vaporizeIntensifiePheromons(List<Double> pheromones, List<Boolean> position, int problemSize) {
+		ListIterator<Double> iterPheromone = pheromones.listIterator();
+		ListIterator<Boolean> iterBest = position.listIterator();
+		for(int i = 0; i < problemSize; i++) {
+			double pheromone = iterPheromone.next();
+			boolean bestDecision = iterBest.next();
+			iterPheromone.set((1.0 - p) * pheromone + (bestDecision?p:0.0));
+		}
+	}
+	/**
+	 * 
+	 * @param pheromones
+	 * @return
+	 */
+	private List<Individual> constructSolutionsBiasedBy(List<Double> pheromones) {
+		List<Individual> population =  new ArrayList<Individual>();
+		for(int i = 0; i < popsize; i++) {
+			population.add(constructASolutionBiasedBy(pheromones));
+		}
+		return population;
+	}
+	
+	
+	/**
+	 * Walks the path with a ant and decide by pheromones if should take true or false;
+	 * A pheromone have a level of 0 < pheromone < 1.
+	 * A Pheromone is  equal to the probability.
+	 * @param pheromones
+	 * @return
+	 */
+	private Individual constructASolutionBiasedBy(List<Double> pheromones) {
+		Individual result = new Individual();
+		result.position = new ArrayList<Boolean>();
+		for(double pheromone : pheromones) {
+			result.position.add((Random.nextDouble() < pheromone));
+		}
+		return result;
+	}
+	/**
+	 * Initialize Pheromons with 0.5
+	 */
+	private List<Double> initPheromones(int problemSize) {
+		List<Double> result = new ArrayList<Double>();
+		for(int i = 0; i < problemSize;i++) {
+			result.add(0.5);
+		}
+		return result;
+	}
+
+	
+}

+ 5 - 5
src/exampleAlgorithms/BaseLine.java

@@ -39,7 +39,7 @@ import javax.swing.JTextArea;
 import javax.swing.filechooser.FileNameExtensionFilter;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -56,7 +56,7 @@ import ui.model.DecoratedState;
 
 
 
-public class BaseLine implements Algorithm {
+public class BaseLine implements AddOn {
 	//Parameter for Algo with default Values:
 	private boolean closeSwitches = true;
 	
@@ -87,7 +87,7 @@ public class BaseLine implements Algorithm {
 	{
 	      JFrame newFrame = new JFrame("exampleWindow");
 	      BaseLine instance = new BaseLine();
-	      newFrame.setContentPane(instance.getAlgorithmPanel());
+	      newFrame.setContentPane(instance.getPanel());
 	      newFrame.pack();
 	      newFrame.setVisible(true);
 	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -218,7 +218,7 @@ public class BaseLine implements Algorithm {
 	
 	
 	private void disableGuiInput(boolean bool) {
-		control.guiDiable(bool);
+		control.guiDisable(bool);
 	}
 	
 	
@@ -227,7 +227,7 @@ public class BaseLine implements Algorithm {
 	
 	
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 	@Override

+ 5 - 5
src/exampleAlgorithms/DemoAlgo.java

@@ -28,7 +28,7 @@ import javax.swing.JSplitPane;
 import javax.swing.JTextArea;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -40,7 +40,7 @@ import ui.model.DecoratedNetwork;
 import ui.model.DecoratedState;
 import ui.model.Model;
 
-public class DemoAlgo implements Algorithm {
+public class DemoAlgo implements AddOn {
 
 	//Parameter for Algo with default Values:
 		private boolean closeSwitches = true;
@@ -80,7 +80,7 @@ public class DemoAlgo implements Algorithm {
 		{
 		      JFrame newFrame = new JFrame("exampleWindow");
 		      DemoAlgo instance = new DemoAlgo();
-		      newFrame.setContentPane(instance.getAlgorithmPanel());
+		      newFrame.setContentPane(instance.getPanel());
 		      newFrame.pack();
 		      newFrame.setVisible(true);
 		      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -244,7 +244,7 @@ public class DemoAlgo implements Algorithm {
 		
 		
 		private void disableGuiInput(boolean bool) {
-			control.guiDiable(bool);
+			control.guiDisable(bool);
 		}
 		
 		
@@ -253,7 +253,7 @@ public class DemoAlgo implements Algorithm {
 		
 		
 		@Override
-		public JPanel getAlgorithmPanel() {
+		public JPanel getPanel() {
 			return content;
 		}
 		@Override

+ 122 - 0
src/exampleAlgorithms/Evaluation.java

@@ -0,0 +1,122 @@
+package exampleAlgorithms;
+
+import classes.HolonObject;
+import ui.model.DecoratedNetwork;
+import ui.model.DecoratedState;
+import ui.controller.FlexManager.FlexState;
+import ui.controller.FlexManager.FlexWrapper;
+import ui.model.DecoratedHolonObject.HolonObjectState;
+
+public class Evaluation {
+	
+	/**
+	 * Calculate the Fitness(Penelty) Value for a state (alias the calculated Position).
+	 * TODO: Make me better Rolf.
+	 * @param state
+	 * @return
+	 */
+	public static double getFitnessValueForState(DecoratedState state) {
+		double fitness = 0.0;
+		double nw_fitness =0.0;
+		double object_fitness = 0.0;
+		double flexFitness = 0.0;
+		// calculate network_fitness
+		for(DecoratedNetwork net : state.getNetworkList()) {
+			float production = net.getSupplierList().stream().map(supplier -> supplier.getEnergyToSupplyNetwork()).reduce(0.0f, (a, b) -> a + b);
+			float consumption = net.getConsumerList().stream().map(con -> con.getEnergyNeededFromNetwork()).reduce(0.0f, (a, b) -> a + b);
+			nw_fitness += Math.abs((production - consumption)/100); //Energy is now everywhere positive
+		}
+		
+		// calculate object_fitness
+		for(DecoratedNetwork net : state.getNetworkList()) {
+			object_fitness += net.getConsumerList().stream().map(con -> holonObjectSupplyPenaltyFunction(con.getSupplyBarPercentage()) + inactiveHolonElementPenalty(con.getModel())).reduce(0.0, (a, b) -> (a + b));
+			//warum war das im network fitness und nicht hier im Object fitness??
+			object_fitness += net.getConsumerList().stream().map(con -> StateToDouble(con.getState())).reduce(0.0, (a,b) -> (a+b));
+			//System.out.console.println("objectfitness for statestuff: " + object_fitness);
+			//object_fitness += net.getPassivNoEnergyList().stream().map(con -> 1000.0).reduce(0.0, (a, b) -> (a + b));
+			object_fitness += net.getPassivNoEnergyList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b));
+			object_fitness += net.getSupplierList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b));
+			object_fitness += net.getConsumerSelfSuppliedList().stream().map(con -> inactiveHolonElementPenalty(con.getModel())).reduce(0.0, (a, b) -> (a + b));
+		}
+		// calculate flexibility fitness
+		for(FlexWrapper flexWrapper :state.getFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)) {
+			flexFitness += flexWrapper.getFlex().cost / (double)flexWrapper.getFlex().getDuration();
+		}
+		
+		fitness = nw_fitness + object_fitness + flexFitness;
+		return fitness;
+	}
+
+	
+	/**
+	 * Untouched:
+	 * Function that returns the fitness depending on the number of elements deactivated in a single holon object
+	 * @param obj Holon Object that contains Holon Elements
+	 * @return fitness value for that object depending on the number of deactivated holon elements
+	 */
+	private static double inactiveHolonElementPenalty(HolonObject obj) {
+		float result = 0;
+		int activeElements = obj.getNumberOfActiveElements();
+		int maxElements = obj.getElements().size();
+		
+		//result = (float) Math.pow((maxElements -activeElements),2)*10;
+		result = (float) Math.pow(5, 4* ( (float) maxElements - (float) activeElements)/ (float) maxElements) - 1;
+		//System.out.console.println("max: " + maxElements + " active: " + activeElements + " results in penalty: " + result);
+	return result;
+		
+	}
+	/**
+	 * Untouched:
+	 * Calculates a penalty value based on the HOs current supply percentage
+	 * @param supplyPercentage
+	 * @return
+	 */
+	private static double holonObjectSupplyPenaltyFunction(float supplyPercentage) {
+		double result = 0;
+		/*if(supplyPercentage == 1)
+			return result;
+		else if(supplyPercentage < 1 && supplyPercentage >= 0.25) // undersupplied inbetween 25% and 100%
+			result = (float) Math.pow(1/supplyPercentage, 2);
+		else if (supplyPercentage < 0.25) //undersupplied with less than 25%
+			result = (float) Math.pow(1/supplyPercentage,2);
+		else if (supplyPercentage < 1.25)  //Oversupplied less than 25%
+			result = (float) Math.pow(supplyPercentage,3) ;
+		else result = (float) Math.pow(supplyPercentage,4); //Oversupplied more than 25%
+		
+		
+		if(Float.isInfinite(result) || Float.isNaN(result))
+			result = 1000;
+	*/
+		if(supplyPercentage <= 1.0) {
+			result = Math.pow(5,((100 - (supplyPercentage*100))/50 + 2)) - Math.pow(5, 2);
+		}
+		else {
+			result = Math.pow(6,((100 - (supplyPercentage*100))/50 + 2)) - Math.pow(6, 2);
+		}
+		
+		return result;
+	}
+	/**
+	 * If you want to get in touch with a reliable state? Working function not in use currently.
+	 * @param state
+	 * @return
+	 */
+	private static double StateToDouble(HolonObjectState state) {
+		switch (state) {
+		case NOT_SUPPLIED:
+			return 150.0;
+		case NO_ENERGY:
+			return 150.0;
+		case OVER_SUPPLIED:
+			return 100.0;
+		case PARTIALLY_SUPPLIED:
+			return 100.0;
+		case PRODUCER:
+			return 0;
+		case SUPPLIED:
+			return 0;
+		default:
+			return 0;
+		}
+	}
+}

+ 3 - 3
src/exampleAlgorithms/ExampleFitnessFunction.java

@@ -11,13 +11,13 @@ import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
 
-import api.Algorithm;
+import api.AddOn;
 import ui.controller.Control;
 import ui.model.DecoratedHolonObject.HolonObjectState;
 import ui.model.DecoratedNetwork;
 import ui.model.DecoratedState;
 
-public class ExampleFitnessFunction implements Algorithm {
+public class ExampleFitnessFunction implements AddOn {
 	private Control  control;
 	private JTextArea textArea;
 	private JPanel content = new JPanel();
@@ -53,7 +53,7 @@ public class ExampleFitnessFunction implements Algorithm {
 		return parameterPanel;
 	}
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 

+ 5 - 5
src/exampleAlgorithms/FlexExample.java

@@ -31,7 +31,7 @@ import javax.swing.JSplitPane;
 import javax.swing.JTextArea;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -48,7 +48,7 @@ import ui.model.DecoratedState;
 import ui.model.Model;
 import ui.model.DecoratedHolonObject.HolonObjectState;
 
-public class FlexExample implements Algorithm {
+public class FlexExample implements AddOn {
 
 	//Parameter for Algo with default Values:
 		private boolean closeSwitches = true;
@@ -89,7 +89,7 @@ public class FlexExample implements Algorithm {
 		{
 		      JFrame newFrame = new JFrame("exampleWindow");
 		      DemoAlgo instance = new DemoAlgo();
-		      newFrame.setContentPane(instance.getAlgorithmPanel());
+		      newFrame.setContentPane(instance.getPanel());
 		      newFrame.pack();
 		      newFrame.setVisible(true);
 		      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -272,7 +272,7 @@ public class FlexExample implements Algorithm {
 		
 		
 		private void disableGuiInput(boolean bool) {
-			control.guiDiable(bool);
+			control.guiDisable(bool);
 		}
 		
 		
@@ -281,7 +281,7 @@ public class FlexExample implements Algorithm {
 		
 		
 		@Override
-		public JPanel getAlgorithmPanel() {
+		public JPanel getPanel() {
 			return content;
 		}
 		@Override

+ 6 - 6
src/exampleAlgorithms/GaAlgorithm.java

@@ -42,7 +42,7 @@ import javax.swing.JSplitPane;
 import javax.swing.JTextArea;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -56,7 +56,7 @@ import ui.model.Model;
 import ui.view.Console;
 import ui.model.DecoratedHolonObject.HolonObjectState;
 
-public class GaAlgorithm implements Algorithm {
+public class GaAlgorithm implements AddOn {
 
 		//Parameter for Algo with default Values:
 		/**
@@ -73,6 +73,7 @@ public class GaAlgorithm implements Algorithm {
 		private double mutateProbabilityInterval = 0.01;
 		private double maxMutationPercent = 0.01;
 		private int rounds = 2;
+		private boolean moreInformation = false;
 		
 		
 		
@@ -80,7 +81,6 @@ public class GaAlgorithm implements Algorithm {
 		private boolean useGroupNode = false;
 		private DecoratedGroupNode dGroupNode = null;
 		private boolean cancel = false;
-		private boolean moreInformation = false;
 		private boolean append = false;
 
 		//Parameter defined by Algo
@@ -117,7 +117,7 @@ public class GaAlgorithm implements Algorithm {
 		{
 		      JFrame newFrame = new JFrame("exampleWindow");
 		      GaAlgorithm instance = new GaAlgorithm();
-		      newFrame.setContentPane(instance.getAlgorithmPanel());
+		      newFrame.setContentPane(instance.getPanel());
 		      newFrame.pack();
 		      newFrame.setVisible(true);
 		      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -482,7 +482,7 @@ public class GaAlgorithm implements Algorithm {
 		}
 		
 		private void disableGuiInput(boolean bool) {
-			control.guiDiable(bool);
+			control.guiDisable(bool);
 		}
 		
 		private void plott() {
@@ -497,7 +497,7 @@ public class GaAlgorithm implements Algorithm {
 		
 		
 		@Override
-		public JPanel getAlgorithmPanel() {
+		public JPanel getPanel() {
 			return content;
 		}
 		@Override

+ 235 - 0
src/exampleAlgorithms/GaAlgorithm2.java

@@ -0,0 +1,235 @@
+package exampleAlgorithms;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.TreeSet;
+
+import javax.swing.JFrame;
+
+import api.AlgorithmFramework;
+import api.AlgorithmFrameworkFlex;
+import ui.model.DecoratedState;
+
+public class GaAlgorithm2 extends AlgorithmFrameworkFlex{
+
+	/**
+	 * Should be even.
+	 */
+	private int popsize = 20;
+	private int maxGenerations = 100;
+	private double tournamentSize = 2.0;
+	private double fixedSwapProbability = 0.02;
+	private boolean useFixedSpawProbability = false;
+	private double fixedMutateProbability = 0.02;
+	private boolean useFixedMutateProbability = false;
+	private boolean useIntervalMutation = true;
+	private double mutateProbabilityInterval = 0.01;
+	private double maxMutationPercent = 0.01;
+	private boolean moreInformation = false;
+	
+	
+	public GaAlgorithm2() {
+		super();
+		addIntParameter("popsize", popsize, intValue -> popsize = intValue, 1);
+		addIntParameter("maxGenerations", maxGenerations, intValue -> maxGenerations = intValue, 1);
+		addDoubleParameter("tournamentSize", tournamentSize, doubleValue -> tournamentSize = doubleValue, 1.0);
+		addDoubleParameter("fixedSwapProbability", fixedSwapProbability, doubleValue -> fixedSwapProbability = doubleValue, 0.0, 1.0);
+		addBooleanParameter("useFixedSpawProbability", useFixedSpawProbability, booleanValue -> useFixedSpawProbability = booleanValue);
+		addDoubleParameter("fixedMutateProbability", fixedMutateProbability, doubleValue -> fixedMutateProbability = doubleValue, 0.0, 1.0);
+		addBooleanParameter("useFixedMutateProbability", useFixedMutateProbability, booleanValue -> useFixedMutateProbability = booleanValue);
+		addBooleanParameter("useIntervalMutation", useIntervalMutation, booleanValue -> useIntervalMutation = booleanValue);
+		addDoubleParameter("mutateProbabilityInterval", mutateProbabilityInterval, doubleValue -> mutateProbabilityInterval = doubleValue, 0.0, 1.0);
+		addDoubleParameter("maxMutationPercent", maxMutationPercent, doubleValue -> maxMutationPercent = doubleValue, 0.0, 1.0);
+		addBooleanParameter("moreInformation", moreInformation, booleanValue -> moreInformation = booleanValue);
+	}
+	
+	public static void main(String[] args)
+	{
+	      JFrame newFrame = new JFrame("exampleWindow");
+	      GaAlgorithm2 instance = new GaAlgorithm2();
+	      newFrame.setContentPane(instance.getPanel());
+	      newFrame.pack();
+	      newFrame.setVisible(true);
+	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+	}
+	
+	@Override
+	protected double evaluateState(DecoratedState actualstate) {
+		return Evaluation.getFitnessValueForState(actualstate);
+	}
+
+
+	@Override
+	protected int getProgressBarMaxCount() {
+		return this.maxGenerations * this.popsize * this.rounds + rounds;
+	}
+	
+	@Override
+	protected Individual executeAlgo() {
+		Individual best = new Individual();
+		best.position = extractPositionAndAccess();
+		if(moreInformation)console.println("Bit-Array_length: " + best.position.size());
+		best.fitness = evaluatePosition(best.position);
+		List<Double> runList = new ArrayList<Double>();
+		runList.add(best.fitness);
+		console.print("Start with: " + best.fitness);
+		if(moreInformation)console.println("");
+		int problemSize = best.position.size();
+		List<Individual> population = initPopuluationRandom(problemSize, best);
+		if(moreInformation)console.println("Size To Test:" + population.size());
+		for(int generation = 0; generation< maxGenerations; generation++) {
+			if(moreInformation)console.println("Generation" + generation + " start with Fitness: " + best.fitness);
+			for(Individual i : population) {
+				i.fitness = evaluatePosition(i.position);
+				if(moreInformation)console.println("Fitness" + i.fitness);
+				if(i.fitness < best.fitness) best = i;
+				
+			}
+			runList.add(best.fitness);
+			List<Individual> childList = new ArrayList<Individual>();
+			for(int k = 0; k<popsize/2; k++) {
+				Individual parentA = selectAParent(population, popsize);
+				Individual parentB = selectAParent(population, popsize);
+				Individual childA = new Individual(parentA);
+				Individual childB = new Individual(parentB);
+				crossover(childA, childB, problemSize);
+				if(useIntervalMutation)mutateInterval(childA, problemSize);else mutate(childA, problemSize);
+				if(useIntervalMutation)mutateInterval(childB, problemSize);else mutate(childB, problemSize);
+				childList.add(childA);
+				childList.add(childB);
+			}
+			population = childList;
+			if(moreInformation)console.println("________________");
+			if(cancel)return null;
+		}
+		
+		
+		console.println("   End with:" + best.fitness);
+		return best;
+	}
+	/**
+	 * Algorithm 22 Bit-Flip Mutation.
+	 * 
+	 */
+	private void mutate(Individual child, int problemSize) {
+		double probability = (this.useFixedMutateProbability) ? this.fixedMutateProbability : 1.0/(double)problemSize;
+		ListIterator<Boolean> iter = child.position.listIterator();
+		while(iter.hasNext()) {
+			boolean boolValue = iter.next();
+			if(Random.nextDouble() <=  probability) {
+				iter.set(!boolValue);
+			}
+		}
+	}
+	
+	/**
+	 * Algorithm rolf
+	 * 
+	 */
+	private void mutateInterval(Individual child, int problemSize) {
+		//If not mutate skip
+		if(Random.nextDouble() >  this.mutateProbabilityInterval) {
+			return;
+		}
+		//println("problemSize:" + problemSize + "    maxMutationPercent:" + maxMutationPercent);
+		int maximumAmountOfMutatedBits = Math.max(1, (int)Math.round(((double) problemSize) * this.maxMutationPercent));
+		int randomUniformAmountOfMutatedValues = Random.nextIntegerInRange(1,maximumAmountOfMutatedBits + 1);
+		
+		//println("max:" + maximumAmountOfMutatedBits + "   actual:" + randomUniformAmountOfMutatedValues);
+		TreeSet<Integer> mutationLocation = new TreeSet<Integer>(); //sortedSet
+		//Choose the location to mutate
+		for(int i = 0; i< randomUniformAmountOfMutatedValues; i++) {
+			boolean success = mutationLocation.add(Random.nextIntegerInRange(0, problemSize));
+			if(!success) i--; //can be add up to some series long loops if maximumAmountOfMutatedBits get closed to problemsize.
+		}
+		//println("Set:" + mutationLocation);
+		ListIterator<Boolean> iter = child.position.listIterator();
+		if(mutationLocation.isEmpty()) return;
+		int firstindex = mutationLocation.pollFirst();
+		while(iter.hasNext()) {
+			int index = iter.nextIndex();
+			boolean boolValue = iter.next();
+			if(index == firstindex) {
+				iter.set(!boolValue);
+				//println("changed Value["+ index +"]");
+				if(mutationLocation.isEmpty()) break;
+				firstindex = mutationLocation.pollFirst();
+			}
+		}
+	}
+	
+	
+	
+	
+	/** 
+	 * Algorithm 25 Uniform Crossover.
+	 * Probability is set to 1/Problemsize when not changed.
+	 */
+	private void crossover(Individual childA, Individual childB, int problemSize) {
+		double probability = (this.useFixedSpawProbability) ? this.fixedSwapProbability : 1.0/(double)problemSize;
+		ListIterator<Boolean> iterA = childA.position.listIterator();
+		ListIterator<Boolean> iterB = childB.position.listIterator();
+		for(int i= 0; i < problemSize; i++) {
+			boolean boolA = iterA.next();
+			boolean boolB = iterB.next();
+			if(Random.nextDouble() <=  probability ) {
+				//Swap 
+				iterA.set(boolB);
+				iterB.set(boolA);
+			}
+		}
+	}
+	/**
+	 * Algorithm 32 Tournament Selection.
+	 * The fitnessValues are calculated for the Population List.
+	 * PseudoCode
+	 */
+	private Individual selectAParent(List<Individual> population,int popsize) {
+		Individual tournamentBest = population.get(Random.nextIntegerInRange(0, popsize));
+		double participants;
+		for(participants = tournamentSize ; participants >= 2; participants -= 1.0) {
+			Individual next = population.get(Random.nextIntegerInRange(0, popsize));
+			if(next.fitness < tournamentBest.fitness) tournamentBest = next;
+		}
+		//if tournament size is not a whole number like 2.5 or 3.6
+		//the remaining part is the chance to fight another time; 2.7 -> 70% chance to fight a second time
+		if( participants > 1) {		
+			if(Random.nextDouble() < participants - 1.0) {
+				//println("Chance to find a match");
+				Individual next = population.get(Random.nextIntegerInRange(0, popsize));
+				if(next.fitness < tournamentBest.fitness) tournamentBest = next;
+			}
+		}
+		return tournamentBest;
+	}
+	/**
+	 * Initialize the Population with Individuals that have a random Position.
+	 */
+	private List<Individual> initPopuluationRandom(int problemSize, Individual startIndidual){
+		List<Individual> population =  new ArrayList<Individual>();
+		for(int i = 0; i < popsize -1; i++) {
+			population.add(createRandomIndividualWithoutFitness(problemSize));
+		}
+		//Add Start Position
+		population.add(new Individual(startIndidual));
+		return population;
+	}
+	
+	
+	
+	/**
+	 * Algorithm 21 The BooleanVeator initialization.
+	 * @param problemSize
+	 * @return
+	 */
+	private Individual createRandomIndividualWithoutFitness(int problemSize) {
+		//create Random Individual Without Fitness
+		Individual result = new Individual();
+		result.position = new ArrayList<Boolean>();
+		for (int index = 0; index < problemSize; index++){
+			result.position.add(Random.nextBoolean());
+		}
+		return result;
+	}
+}

+ 6 - 6
src/exampleAlgorithms/PSOAlgorithm.java

@@ -42,7 +42,7 @@ import javax.swing.JTextArea;
 import javax.swing.filechooser.FileNameExtensionFilter;
 import javax.swing.text.NumberFormatter;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -60,7 +60,7 @@ import ui.model.DecoratedState;
 
 
 
-public class PSOAlgorithm implements Algorithm {
+public class PSOAlgorithm implements AddOn {
 	//Parameter for Algo with default Values:
 	private int swarmSize = 150; 
 	private int maxIterations = 200; 
@@ -73,6 +73,7 @@ public class PSOAlgorithm implements Algorithm {
 	private double maxMutationPercent = 0.01;
 	
 	
+	private double c1, c2, w;
 	
 	
 	//Settings For GroupNode using and plotting
@@ -83,7 +84,6 @@ public class PSOAlgorithm implements Algorithm {
 	//Parameter defined by Algo
 	private HashMap<Integer, AccessWrapper> access;
 	LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
-	private double c1, c2, w;
 	private RunDataBase db;
 	
 	//Parameter for Plotting (Default Directory in Constructor)
@@ -106,7 +106,7 @@ public class PSOAlgorithm implements Algorithm {
 	{
 	      JFrame newFrame = new JFrame("exampleWindow");
 	      PSOAlgorithm instance = new PSOAlgorithm();
-	      newFrame.setContentPane(instance.getAlgorithmPanel());
+	      newFrame.setContentPane(instance.getPanel());
 	      newFrame.pack();
 	      newFrame.setVisible(true);
 	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -412,7 +412,7 @@ public class PSOAlgorithm implements Algorithm {
 		disableGuiInput(false);
 	}
 	private void disableGuiInput(boolean bool) {
-		control.guiDiable(bool);
+		control.guiDisable(bool);
 	}
 	
 	private void cancel() {
@@ -490,7 +490,7 @@ public class PSOAlgorithm implements Algorithm {
 		console.println("SwarmSize:" + swarmSize + ", MaxIter:" + maxIterations + ", Limit:" + limit + ", Dependency:" + dependency + ", Rounds:" + rounds +", DependentParameter: w:"+ w + ", c1:" + c1 + ", c2:" + c2 );
 	}
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 	@Override

+ 324 - 0
src/exampleAlgorithms/PsoAlgorithm2.java

@@ -0,0 +1,324 @@
+package exampleAlgorithms;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import javax.swing.JFrame;
+
+import api.AlgorithmFramework;
+import api.AlgorithmFrameworkFlex;
+import ui.model.DecoratedState;
+
+public class PsoAlgorithm2 extends AlgorithmFrameworkFlex{
+	//Parameter for Algo with default Values:
+	private int swarmSize = 20; 
+	private int maxIterations = 100; 
+	private double limit = 0.01; 
+	private double dependency = 2.07; 
+	private int mutationInterval = 1;
+	private boolean useIntervalMutation = true;
+	private double mutateProbabilityInterval = 0.01;
+	private double maxMutationPercent = 0.01;
+	private double c1, c2, w;
+	
+	
+	
+	public static void main(String[] args)
+	{
+	      JFrame newFrame = new JFrame("exampleWindow");
+	      PsoAlgorithm2 instance = new PsoAlgorithm2();
+	      newFrame.setContentPane(instance.getPanel());
+	      newFrame.pack();
+	      newFrame.setVisible(true);
+	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+	}
+	
+	
+	public PsoAlgorithm2() {
+		super();
+		addIntParameter("swarmSize", swarmSize, intValue -> swarmSize = intValue, 1);
+		addIntParameter("maxIterations", maxIterations, intValue -> maxIterations = intValue, 1);
+		addIntParameter("mutationInterval", mutationInterval, intValue -> mutationInterval = intValue, 0);
+		addDoubleParameter("dependency", dependency, doubleValue -> dependency = doubleValue, 2.001, 2.4);
+		addDoubleParameter("limit", limit, doubleValue -> limit = doubleValue, 0.0, 1.0);
+		addBooleanParameter("useIntervalMutation", useIntervalMutation, booleanValue -> useIntervalMutation = booleanValue);
+		addDoubleParameter("mutateProbabilityInterval", mutateProbabilityInterval, doubleValue -> mutateProbabilityInterval = doubleValue, 0.0, 1.0);
+		addDoubleParameter("maxMutationPercent", maxMutationPercent, doubleValue -> maxMutationPercent = doubleValue, 0.0, 1.0);
+	}
+	
+	@Override
+	protected double evaluateState(DecoratedState actualstate) {
+		return Evaluation.getFitnessValueForState(actualstate);
+	}
+
+
+	@Override
+	protected int getProgressBarMaxCount() {
+		return swarmSize * (maxIterations + 1)* rounds + rounds;
+	}
+	/**
+	 *  <p>Algo from Paper:</p><font size="3"><pre>
+	 *  
+	 *  Begin
+	 *  	t = 0; {t: generation index}
+	 *  	initialize particles x<sub>p,i,j</sub>(t);
+	 *  	evaluation x<sub>p,i,j</sub>(t);
+	 *  	while (termination condition &ne; true) do
+	 *  		v<sub>i,j</sub>(t) = update v<sub>i,j</sub>(t); {by Eq. (6)}
+	 *  		x<sub>g,i,j</sub>(t) = update x<sub>g,i,j</sub>(t); {by Eq. (7)}
+	 *  		x<sub>g,i,j</sub>(t) = mutation x<sub>g,i,j</sub>(t); {by Eq. (11)}
+	 *  		x<sub>p,i,j</sub>(t) = decode x<sub>g,i,j</sub>(t); {by Eqs. (8) and (9)}
+	 *  		evaluate x<sub>p,i,j</sub>(t);
+	 *  		t = t + 1;
+	 *  	end while
+	 *  End</pre></font>
+	 *  <p>with:</p><font size="3">
+	 *  
+	 *  x<sub>g,i,j</sub>: genotype ->genetic information -> in continuous space<br>
+	 *  x<sub>p,i,j</sub>: phenotype -> observable characteristics-> in binary space<br>
+	 *  X<sub>g,max</sub>: is the Maximum here set to 4.<br>
+	 *  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>
+	 *  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>
+	 *  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>
+	 *  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>
+	 *  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>
+	 *  <p>Parameter:</p>
+	 *  w inertia, calculated from phi(Variable:{@link #dependency})<br>
+	 *  c1:	influence, calculated from phi(Variable:{@link #dependency}) <br>
+	 *  c2:	influence, calculated from phi(Variable:{@link #dependency})<br>
+	 *  r<sub>mu</sub>: probability that the proposed operation is conducted defined by limit(Variable:{@link #limit})<br>
+	 *  
+	 *  
+	 */
+	@Override
+	protected Individual executeAlgo() {
+		initDependentParameter();
+		Individual globalBest = new Individual();
+		globalBest.position = extractPositionAndAccess();
+		globalBest.fitness = evaluatePosition(globalBest.position);
+		console.println("Start Value:" + globalBest.fitness);
+		int dimensions = globalBest.position.size();
+		List<Particle> swarm= initializeParticles(dimensions);
+		List<Double> runList = new ArrayList<Double>();
+		runList.add(globalBest.fitness);
+		evaluation(globalBest, swarm);
+		runList.add(globalBest.fitness);
+		for (int iteration = 0; iteration < maxIterations ; iteration++) {
+			int mutationAllowed = iteration % mutationInterval;
+			for (int particleNumber = 0; particleNumber < swarmSize; particleNumber++) {
+				Particle particle = swarm.get(particleNumber);		
+				
+				if(this.useIntervalMutation) {
+					boolean allowMutation = (Random.nextDouble() <  this.mutateProbabilityInterval);
+					TreeSet<Integer> mutationLocation = null;
+					if(allowMutation)mutationLocation = locationsToMutate(dimensions);
+					for(int index = 0; index < dimensions; index++) {
+						updateVelocity(particle, index, globalBest);
+						updateGenotype(particle, index);
+						if(allowMutation &&mutationAllowed == 0 && iteration != 0 && mutationLocation.contains(index))mutation(particle, index);
+						decode(particle, index);
+					}
+				}else {					
+					for(int index = 0; index < dimensions; index++) {
+						updateVelocity(particle, index, globalBest);
+						updateGenotype(particle, index);
+						if(mutationAllowed == 0 && iteration != 0)mutation(particle, index);
+						decode(particle, index);
+					}
+				}
+			}
+			if(cancel)return null;
+			evaluation(globalBest, swarm);
+			runList.add(globalBest.fitness);
+		}
+		console.println(" End Value:" + globalBest.fitness);
+		db.insertNewRun(runList);
+		return globalBest;
+	}
+	/**
+	 * 
+	 * @param j maximum index of position in the particle
+	 * @return
+	 */
+	private List<Particle> initializeParticles(int j) {
+		List<Particle> swarm = new ArrayList<Particle>();
+		//Create The Particle
+		for (int particleNumber = 0; particleNumber < swarmSize; particleNumber++){
+			//Create a Random position
+			List<Boolean> aRandomPosition = new ArrayList<Boolean>();
+			for (int index = 0; index < j; index++){
+				aRandomPosition.add(Random.nextBoolean());
+			}
+			swarm.add(new Particle(aRandomPosition));
+		}
+		return swarm;
+	}
+	/**
+	 * Calculate w, c1, c2
+	 */
+	private void initDependentParameter() {
+		w = 1.0 / (dependency - 1 + Math.sqrt(dependency * dependency - 2 * dependency));
+		c1 = c2 = dependency * w;
+	}
+	/**
+	 * Evaluate each particle and update the global Best position;
+	 * @param globalBest
+	 * @param swarm
+	 */
+	private void evaluation(Individual globalBest, List<Particle> swarm) {
+		for(Particle p: swarm) {
+			double localEvaluationValue = evaluatePosition(p.xPhenotype);
+			p.checkNewEvaluationValue(localEvaluationValue);
+			if(localEvaluationValue < globalBest.fitness) {
+				globalBest.fitness = localEvaluationValue;
+				globalBest.position = p.localBest.position;
+			}
+		}
+	}
+	/**
+	 * 	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>
+	 * @param particle
+	 * @param index
+	 * @param globalBest
+	 */
+	private void updateVelocity(Particle particle, int index, Individual globalBest) {
+		double r1 = Random.nextDouble();
+		double r2 =	Random.nextDouble();
+		double posValue = particle.xPhenotype.get(index)?1.0:0.0;
+		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)) );
+	}
+	/**
+	 * 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>
+	 * @param particle
+	 * @param index
+	 */
+	private void updateGenotype(Particle particle, int index) {
+		particle.xGenotype.set(index, clamp(particle.xGenotype.get(index) + particle.velocity.get(index)));
+	}
+	/**
+	 * 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>
+	 * @param particle
+	 * @param index
+	 */
+	private void mutation(Particle particle, int index) {
+		if(Random.nextDouble() < limit) particle.xGenotype.set(index, -particle.xGenotype.get(index));
+	}
+	/**
+	 * 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>
+	 * @param particle
+	 * @param index
+	 */
+	private void decode(Particle particle, int index) {
+		particle.xPhenotype.set(index, Random.nextDouble() < Sigmoid(particle.xGenotype.get(index)));
+	}
+	/**
+	 * 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>
+	 * @param value
+	 * @return
+	 */
+	private double Sigmoid(double value) {
+		return 1.0 / (1.0 + Math.exp(-value));
+	}
+
+	/**
+	 * 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}
+	 * @param value
+	 * @return
+	 */
+	private double clamp(double value) {
+		return Math.max(-4.0, Math.min(4.0, value));
+	}
+	private TreeSet<Integer> locationsToMutate(int dimensions) {
+		TreeSet<Integer> mutationLocation = new TreeSet<Integer>(); //sortedSet
+		int maximumAmountOfMutatedBits = Math.max(1, (int)Math.round(((double) dimensions) * this.maxMutationPercent));
+		int randomUniformAmountOfMutatedValues = Random.nextIntegerInRange(1,maximumAmountOfMutatedBits + 1);
+		for(int i = 0; i< randomUniformAmountOfMutatedValues; i++) {
+			boolean success = mutationLocation.add(Random.nextIntegerInRange(0, dimensions));
+			if(!success) i--; //can be add up to some series long loops if maximumAmountOfMutatedBits get closed to problemsize.
+		}
+		//console.println(mutationLocation.toString());
+		return mutationLocation;
+	}
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	/**
+	 * Class to represent a Particle.
+	 */
+	private class Particle{
+		/**
+		 * The velocity of a particle.
+		 */
+		public List<Double> velocity;
+		/**
+		 * The positions genotype.
+		 */
+		public List<Double> xGenotype;
+		/**
+		 * The positions phenotype. Alias the current position.
+		 */
+		public List<Boolean> xPhenotype;
+		
+		public Individual localBest;
+		
+		Particle(List<Boolean> position){
+			this.xPhenotype = position;
+			//Init velocity, xGenotype with 0.0 values.
+			this.velocity = position.stream().map(bool -> 0.0).collect(Collectors.toList());
+			this.xGenotype = position.stream().map(bool -> 0.0).collect(Collectors.toList());
+			localBest = new Individual();
+			localBest.fitness = Double.MAX_VALUE;
+		}
+		public void checkNewEvaluationValue(double newEvaluationValue) {
+			if(newEvaluationValue < localBest.fitness) {
+				localBest.fitness = newEvaluationValue;
+				localBest.position = xPhenotype.stream().map(bool -> bool).collect(Collectors.toList());
+			}
+		}
+		public String toString() {
+			return "Particle with xPhenotype(Position), xGenotype, velocity:[" 
+					+ listToString(xPhenotype) + "],[" + listToString(xGenotype) + "],[" 
+					+ listToString(velocity) + "]";
+		}
+		private <Type> String listToString(List<Type> list) {
+			return list.stream().map(Object::toString).collect(Collectors.joining(", "));
+		}
+		
+	}
+		
+		
+		
+		
+		
+
+}

+ 4 - 4
src/exampleAlgorithms/RandomPriority.java

@@ -15,7 +15,7 @@ import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JSlider;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -31,7 +31,7 @@ import ui.controller.Control;
  */
 
 
-public class RandomPriority implements Algorithm {
+public class RandomPriority implements AddOn {
 	/**
 	 * Its like a Gradient the Values are on one Axis from Start to End:
 	 * |--start--lm--mh--he--end--|
@@ -57,7 +57,7 @@ public class RandomPriority implements Algorithm {
 	{
 	      JFrame newFrame = new JFrame("exampleWindow");
 	      RandomPriority instance = new RandomPriority();
-	      newFrame.setContentPane(instance.getAlgorithmPanel());
+	      newFrame.setContentPane(instance.getPanel());
 	      newFrame.pack();
 	      newFrame.setVisible(true);
 	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -197,7 +197,7 @@ public class RandomPriority implements Algorithm {
 	
 	
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 	@Override

+ 3 - 3
src/exampleAlgorithms/RandomSwitch.java

@@ -12,11 +12,11 @@ import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JSlider;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.HolonSwitch;
 import ui.controller.Control;
 
-public class RandomSwitch implements Algorithm {
+public class RandomSwitch implements AddOn {
 	private double  randomChance = 0.5;
 	private Control  control;
 	
@@ -75,7 +75,7 @@ public class RandomSwitch implements Algorithm {
 		control.updateCanvas();
 	}
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 	@Override

+ 4 - 4
src/exampleAlgorithms/Randomizer.java

@@ -29,7 +29,7 @@ import com.google.gson.JsonIOException;
 import com.google.gson.JsonParser;
 import com.google.gson.JsonSyntaxException;
 
-import api.Algorithm;
+import api.AddOn;
 import classes.AbstractCpsObject;
 import classes.CpsUpperNode;
 import classes.HolonElement;
@@ -38,7 +38,7 @@ import classes.HolonSwitch;
 import ui.controller.Control;
 import ui.model.Model;
 
-public class Randomizer implements Algorithm {
+public class Randomizer implements AddOn {
 	private Control  control;
 	private int minAmountOfElements = 3;
 	private int maxAmountOfElements = 7;
@@ -48,7 +48,7 @@ public class Randomizer implements Algorithm {
     {
         JFrame newFrame = new JFrame("exampleWindow");
         Randomizer instance = new Randomizer();
-        newFrame.setContentPane(instance.getAlgorithmPanel());
+        newFrame.setContentPane(instance.getPanel());
         newFrame.pack();
         newFrame.setVisible(true);
 	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -150,7 +150,7 @@ public class Randomizer implements Algorithm {
 	
 	
 	@Override
-	public JPanel getAlgorithmPanel() {
+	public JPanel getPanel() {
 		return content;
 	}
 	@Override

+ 1 - 1
src/ui/controller/Control.java

@@ -1031,7 +1031,7 @@ public class Control {
 		return gui;
 	}
 
-	public void guiDiable(boolean state) {
+	public void guiDisable(boolean state) {
 		gui.guiDisable(state);
 	}
 	

+ 16 - 1
src/ui/controller/FlexManager.java

@@ -78,7 +78,10 @@ public class FlexManager {
 			if(flexToOrder!=null)flexToOrder.order();
 		});
 	}
-	
+	public void orderFlex(Flexibility flex) {
+		FlexWrapper flexToOrder =  accessFlexMap.get(flex);
+		if(flexToOrder!=null)flexToOrder.order();
+	}
 	public boolean isAFlexInUseOfHolonElement(HolonElement ele) {
 		return ele.flexList.stream().filter(flex -> this.accessFlexMap.containsKey(flex)).anyMatch(flex -> (this.accessFlexMap.get(flex).getState() == FlexState.IN_USE));
 	}
@@ -141,6 +144,18 @@ public class FlexManager {
 			}
 			return false;
 		}
+		public boolean cancel() {
+			if(allFlexesOrderedThisTimeStep.contains(flex)) {
+				state=FlexState.OFFERED;
+				durationEndTime = -1;
+				coolDownEndTime = -1;
+				allFlexesOrderedThisTimeStep.remove(flex);
+				accessFlexMap.values().stream().filter(flexWrapper -> (flexWrapper.getFlex().getElement() == flex.getElement() && flexWrapper != this)).forEach(otherFlex -> otherFlex.revalidateState());
+				
+				return true;
+			}
+			return false;
+		}
 		public int remainingTimeTillActivation() {
 			return Math.max(0, coolDownEndTime - timeStep);
 		}

+ 11 - 1
src/ui/controller/SimulationManager.java

@@ -57,6 +57,12 @@ public class SimulationManager {
 	public SimulationManager(Model m) {
 		model = m;
 	}
+	
+	
+	
+	
+	
+	
 	/**
 	 * calculates the flow of the edges and the supply for objects and consider old timesteps for burned cables.
 	 *
@@ -125,7 +131,7 @@ public class SimulationManager {
 			leftOverDecoratedCables.add(new DecoratedCable(cable.getModel(), cable.getState(), 0.0f));
 		}
 		ArrayList<DecoratedSwitch> listOfDecoratedSwitches = decorateSwitches(minimumModel, timestep);
-		DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, timestep);
+		DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, flexManagerFromActual, timestep);
 		saves.put(timestep, stateFromThisTimestep);
 		if(updateVisual)savesVisual.put(timestep, new VisualRepresentationalState(stateFromThisTimestep, minimumModel));
 	}
@@ -261,6 +267,10 @@ public class SimulationManager {
 	public void resetFlexManager(){
 		savesFlexManger.clear();
 	}
+	public void resetFlexManagerForTimeStep(int timestep) {
+		FlexManager newFlexManager = new FlexManager(model, timestep, savesFlexManger.getOrDefault(timestep-1, null));
+		savesFlexManger.put(timestep, newFlexManager);
+	}
 	
 	public DecoratedState getDecorState(int timestep) {
 		return saves.getOrDefault(timestep, null);

+ 8 - 1
src/ui/model/DecoratedState.java

@@ -2,17 +2,21 @@ package ui.model;
 
 import java.util.ArrayList;
 
+import ui.controller.FlexManager;
+
 
 public class DecoratedState {
 	int timestepOfState;
 	ArrayList<DecoratedNetwork> networkList;
 	ArrayList<DecoratedCable> leftOverEdges;
 	ArrayList<DecoratedSwitch> decoratedSwitches;
-	public DecoratedState(ArrayList<DecoratedNetwork> networkList, ArrayList<DecoratedCable> leftOverEdges, ArrayList<DecoratedSwitch> decoratedSwitches , int timestepOfState){
+	FlexManager flexManager;
+	public DecoratedState(ArrayList<DecoratedNetwork> networkList, ArrayList<DecoratedCable> leftOverEdges, ArrayList<DecoratedSwitch> decoratedSwitches, FlexManager flexManager , int timestepOfState){
 		this.networkList = networkList;
 		this.leftOverEdges = leftOverEdges;
 		this.decoratedSwitches = decoratedSwitches;
 		this.timestepOfState = timestepOfState;
+		this.flexManager = flexManager;
 	}
 	public ArrayList<DecoratedNetwork> getNetworkList() {
 		return networkList;
@@ -23,6 +27,9 @@ public class DecoratedState {
 	public ArrayList<DecoratedSwitch> getDecoratedSwitches() {
 		return decoratedSwitches;
 	}
+	public FlexManager getFlexManager() {
+		return flexManager;
+	}
 	public int getTimestepOfState() {
 		return timestepOfState;
 	}

+ 11 - 12
src/ui/view/AlgoWindow.java → src/ui/view/AddOnWindow.java

@@ -31,18 +31,17 @@ import javax.swing.text.StyledDocument;
 import javax.tools.JavaCompiler;
 import javax.tools.ToolProvider;
 
-import api.Algorithm;
+import api.AddOn;
 import ui.controller.Control;
 
-//TODO delete old class AlgorithmMenu and change this class to AlgorithmMenu;
 @SuppressWarnings("serial")
-public class AlgoWindow extends JFrame{
-	private Algorithm actual;
+public class AddOnWindow extends JFrame{
+	private AddOn actual;
 	private Control control;
 	private JPanel content = new JPanel();
-	AlgoWindow(JFrame parentFrame, Control control){
+	AddOnWindow(JFrame parentFrame, Control control){
 		this.control = control;
-		this.setTitle("Algorithm");
+		this.setTitle("Add-Ons");
 		this.setVisible(true);
 		this.setContentPane(content);
 		this.setIconImage(Util.loadImage("/Images/Holeg.png", 30, 30));
@@ -75,11 +74,11 @@ public class AlgoWindow extends JFrame{
 		textPane.setParagraphAttributes(attribs, true);
 		textPane.setText("No algorithm is loaded."
 				+"\n OPTION[1]:"
-				+"\n  Select '.java'-file via the file browser. (File\u2192Open .jave-File..)"
+				+"\n  Select '.java'-file via the file browser. (File\u2192Open .jave-File..)"
 				+"\n"
 				+"\n OPTION[2]:"
-				+"\n• First select the folder where the algorithm '.java'-file is located. (File\u2192Open Folder..)"
-				+"\n Second load the algorithm. (File\u2192'YourAlgo')");
+				+"\n First select the folder where the addon '.java'-file is located. (File\u2192Open Folder..)"
+				+"\n Second load the algorithm. (File\u2192'YourAlgo')");
 		textPane.setFont(new Font("Serif", Font.PLAIN, 16));
 		
 		
@@ -160,12 +159,12 @@ public class AlgoWindow extends JFrame{
 		URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { folder.toURI().toURL() });
 		Class<?> cls = Class.forName(packageName.isEmpty()?name:packageName + "." +name, true, classLoader);
 		Object object = cls.newInstance();
-		if(!(object instanceof Algorithm)) {
+		if(!(object instanceof AddOn)) {
 			generateErrorDialog("Class does not implement CpsAlgorithm!");
 		}else {
-			actual = (Algorithm)object;
+			actual = (AddOn)object;
 			actual.setController(control);
-			this.setContentPane(actual.getAlgorithmPanel());
+			this.setContentPane(actual.getPanel());
 			this.pack();
 		}
 		} catch (MalformedURLException e) {

+ 1 - 1
src/ui/view/GUI.java

@@ -2513,7 +2513,7 @@ public class GUI implements CategoryListener {
 		//Algo
 		JMenuItem openMenu =  new JMenuItem("Open Algorithm Panel", new ImageIcon(Util.loadImage("/Button_Images/iconAlgo.png").getScaledInstance(20, 20, java.awt.Image.SCALE_SMOOTH)));
 		openMenu.addActionListener(actionEvent -> {
-			new AlgoWindow(holegJFrame, controller);
+			new AddOnWindow(holegJFrame, controller);
 		});
 		openMenu.setAccelerator(KeyStroke.getKeyStroke('N', Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask()));
 		menuWindow.add(openMenu);