Browse Source

GA Algorithm base

Tom Troppmann 5 years ago
parent
commit
67db855535
2 changed files with 809 additions and 9 deletions
  1. 797 0
      src/exampleAlgorithms/GaAlgorithm.java
  2. 12 9
      src/exampleAlgorithms/PSOAlgorithm.java

+ 797 - 0
src/exampleAlgorithms/GaAlgorithm.java

@@ -0,0 +1,797 @@
+package exampleAlgorithms;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.image.BufferedImage;
+import java.math.RoundingMode;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.stream.Collectors;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFormattedTextField;
+import javax.swing.JFrame;
+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.JTextArea;
+import javax.swing.text.NumberFormatter;
+
+import api.Algorithm;
+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.model.DecoratedHolonObject.HolonObjectState;
+
+public class GaAlgorithm implements Algorithm {
+
+		//Parameter for Algo with default Values:
+		/**
+		 * Should be even.
+		 */
+		private int popsize = 20;
+		private int maxGenerations = 100;
+		private int tournamentSize = 2;
+		private double fixedSwapProbability = 0.02;
+		private boolean useFixedSpawProbability = false;
+		private double fixedMutateProbability = 0.02;
+		private boolean useFixedMutateProbability = false;
+		private int rounds = 2;
+		
+		
+		
+		//Settings For GroupNode using and cancel
+		private boolean useGroupNode = false;
+		private DecoratedGroupNode dGroupNode = null;
+		private boolean cancel = false;
+		
+		
+
+		//Parameter defined by Algo
+		private HashMap<Integer, AccessWrapper> access;
+		LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
+		private List<Boolean> initialState;
+		private List<HolonSwitch> switchList;
+		private List<HolonObject> objectList;
+		
+		//Gui Part:
+		private Control  control;
+		private JTextArea textArea;
+		private JPanel content = new JPanel();
+		//ProgressBar
+		private JProgressBar progressBar = new JProgressBar();
+		private int progressBarCount = 0;
+		private long startTime;
+		private Thread runThread;
+
+
+
+
+
+		
+		
+		
+		
+		
+		
+		
+		public static void main(String[] args)
+		{
+		      JFrame newFrame = new JFrame("exampleWindow");
+		      GaAlgorithm instance = new GaAlgorithm();
+		      newFrame.setContentPane(instance.getAlgorithmPanel());
+		      newFrame.pack();
+		      newFrame.setVisible(true);
+		      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		}
+		public GaAlgorithm() {
+			content.setLayout(new BorderLayout());
+		
+			textArea = new JTextArea();
+			textArea.setEditable(false);
+			JScrollPane scrollPane = new JScrollPane(textArea);
+			JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+					createOptionPanel() , scrollPane);
+			splitPane.setResizeWeight(0.0);
+			content.add(splitPane, BorderLayout.CENTER);
+			content.setPreferredSize(new Dimension(800,800));	
+		}
+		public JPanel createOptionPanel() {
+			JPanel optionPanel = new JPanel(new BorderLayout());
+			JScrollPane scrollPane = new JScrollPane(createParameterPanel());
+			scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter"));
+			optionPanel.add(scrollPane,  BorderLayout.CENTER);
+			optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
+			return optionPanel;
+		}
+		
+		private Component createParameterPanel() {
+			JPanel parameterPanel = new JPanel(null);
+			parameterPanel.setPreferredSize(new Dimension(510,300));
+			
+			
+				
+			JLabel maxGenerationsLabel = new JLabel("Max. Generations:");
+			maxGenerationsLabel.setBounds(20, 60, 150, 20);
+			parameterPanel.add(maxGenerationsLabel);
+			
+			JLabel populationLabel = new JLabel("Population Size:");
+			populationLabel.setBounds(20, 85, 150, 20);
+			parameterPanel.add(populationLabel);
+			
+			JLabel roundLabel = new JLabel("Rounds:");
+			roundLabel.setBounds(20, 110, 150, 20);
+			parameterPanel.add(roundLabel);
+			
+			JLabel mutationLabel = new JLabel("FixedMutation:");
+			mutationLabel.setBounds(50, 135, 150, 20);
+			mutationLabel.setEnabled(useFixedMutateProbability);
+			parameterPanel.add(mutationLabel);
+			
+		
+			JLabel swapLabel = new JLabel("FixedSwap:");
+			swapLabel.setBounds(50, 160, 150, 20);
+			swapLabel.setEnabled(this.useFixedSpawProbability);
+			parameterPanel.add(swapLabel);
+			
+			
+			JLabel progressLabel = new JLabel("Progress:");
+			progressLabel.setBounds(350, 135, 170, 20);
+			parameterPanel.add(progressLabel);	
+			
+			progressBar.setBounds(350, 155, 185, 20);
+			progressBar.setStringPainted(true);
+			parameterPanel.add(progressBar);
+			
+			JPanel borderPanel = new JPanel(null);
+			borderPanel.setBounds(350, 85, 185, 50);
+			borderPanel.setBorder(BorderFactory.createTitledBorder(""));
+			parameterPanel.add(borderPanel);	
+			
+			JLabel showGroupNodeLabel = new JLabel("Use Group Node:");
+			showGroupNodeLabel.setBounds(10, 1, 170, 20);
+			borderPanel.add(showGroupNodeLabel);	
+			
+			JButton selectGroupNodeButton = new JButton("Select GroupNode");
+			selectGroupNodeButton.setEnabled(false);
+			selectGroupNodeButton.setBounds(10, 25, 165, 20);
+			selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode());
+			borderPanel.add(selectGroupNodeButton);	
+			
+			JCheckBox useGroupNodeCheckBox = new JCheckBox();
+			useGroupNodeCheckBox.setSelected(false);
+			useGroupNodeCheckBox.setBounds(155, 1, 25, 20);
+			useGroupNodeCheckBox.addActionListener(actionEvent -> {
+				useGroupNode = useGroupNodeCheckBox.isSelected();
+				selectGroupNodeButton.setEnabled(useGroupNode);
+			});
+			borderPanel.add(useGroupNodeCheckBox);
+			
+	
+			//Integer formatter
+			NumberFormat format = NumberFormat.getIntegerInstance();
+			format.setGroupingUsed(false);
+			format.setParseIntegerOnly(true);
+			NumberFormatter integerFormatter = new NumberFormatter(format);
+			integerFormatter.setMinimum(1);
+			integerFormatter.setCommitsOnValidEdit(true);
+			
+			
+			JFormattedTextField maxGenerationsTextField = new  JFormattedTextField(integerFormatter);
+			maxGenerationsTextField.setValue(this.maxGenerations);
+			maxGenerationsTextField.setToolTipText("Only positive Integer.");
+			maxGenerationsTextField.addPropertyChangeListener(actionEvent -> this.maxGenerations = Integer.parseInt(maxGenerationsTextField.getValue().toString()));
+			maxGenerationsTextField.setBounds(160, 60, 50, 20);
+			parameterPanel.add(maxGenerationsTextField);
+			
+			JFormattedTextField popSizeTextField = new JFormattedTextField(integerFormatter);
+			popSizeTextField.setValue(this.popsize);
+			popSizeTextField.setToolTipText("Only positive Integer.");
+			popSizeTextField.addPropertyChangeListener(propertyChange -> this.popsize = Integer.parseInt(popSizeTextField.getValue().toString()));
+			popSizeTextField.setBounds(160, 85, 50, 20);
+			parameterPanel.add(popSizeTextField);
+			
+			
+			JFormattedTextField roundsTextField = new JFormattedTextField(integerFormatter);
+			roundsTextField.setValue(this.rounds);
+			roundsTextField.setToolTipText("Only positive Integer.");
+			roundsTextField.addPropertyChangeListener(propertyChange -> this.rounds = Integer.parseInt(roundsTextField.getValue().toString()));
+			roundsTextField.setBounds(160, 110, 50, 20);
+			parameterPanel.add(roundsTextField);
+			
+			
+			//Double Format:
+			NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
+			doubleFormat.setMinimumFractionDigits(1);
+			doubleFormat.setMaximumFractionDigits(3);
+			doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
+
+			//Limit Formatter:
+			NumberFormatter limitFormatter = new NumberFormatter(doubleFormat);
+			limitFormatter.setMinimum(0.0);
+			limitFormatter.setMaximum(1.0);
+			
+			JFormattedTextField mutateTextField = new JFormattedTextField(limitFormatter);
+			mutateTextField.setValue(this.fixedMutateProbability);
+			mutateTextField.setEnabled(this.useFixedMutateProbability);
+			mutateTextField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
+			mutateTextField.addPropertyChangeListener(propertyChange -> fixedMutateProbability = Double.parseDouble(mutateTextField.getValue().toString()));
+			mutateTextField.setBounds(160, 135, 50, 20);
+			parameterPanel.add(mutateTextField);
+			
+			JCheckBox useFixMutateCheckBox = new JCheckBox();
+			useFixMutateCheckBox.setSelected(this.useFixedMutateProbability);
+			useFixMutateCheckBox.setToolTipText("If not checked its 1/ProblemSize");
+			useFixMutateCheckBox.setBounds(20, 135, 25, 20);
+			useFixMutateCheckBox.addActionListener(actionEvent -> {
+				boolean state = useFixMutateCheckBox.isSelected();
+				this.useFixedMutateProbability = state;
+				mutateTextField.setEnabled(state);
+				mutationLabel.setEnabled(state);
+			});
+			parameterPanel.add(useFixMutateCheckBox);
+			
+			
+			JFormattedTextField swapTextField = new JFormattedTextField(limitFormatter);
+			swapTextField.setValue(this.fixedSwapProbability);
+			swapTextField.setEnabled(this.useFixedMutateProbability);
+			swapTextField.setToolTipText("Only Double in range [0.0, 1.0] with DecimalSeperator Point('.').");
+			swapTextField.addPropertyChangeListener(propertyChange -> this.fixedSwapProbability = Double.parseDouble(swapTextField.getValue().toString()));
+			swapTextField.setBounds(160, 160, 50, 20);
+			parameterPanel.add(swapTextField);
+			
+			JCheckBox useFixSwapCheckBox = new JCheckBox();
+			useFixSwapCheckBox.setSelected(this.useFixedSpawProbability);
+			useFixSwapCheckBox.setToolTipText("If not checked its 1/ProblemSize");
+			useFixSwapCheckBox.setBounds(20, 160, 25, 20);
+			useFixSwapCheckBox.addActionListener(actionEvent -> {
+				boolean state = useFixSwapCheckBox.isSelected();
+				this.useFixedSpawProbability = state;
+				swapTextField.setEnabled(state);
+				swapLabel.setEnabled(state);
+			});
+			parameterPanel.add(useFixSwapCheckBox);
+			
+			
+			return parameterPanel;
+		}
+		public JPanel createButtonPanel() {
+			JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+			JButton resetButton =  new JButton("ResetAll");
+			resetButton.setToolTipText("Resets the State to before the Algorithm has runed.");
+			resetButton.addActionListener(actionEvent -> resetAll());
+			buttonPanel.add(resetButton);
+			JButton cancelButton =  new JButton("Cancel Run");
+			cancelButton.addActionListener(actionEvent -> cancel());
+			buttonPanel.add(cancelButton);
+			JButton clearButton =  new JButton("Clear Console");
+			clearButton.addActionListener(actionEvent -> clear());
+			buttonPanel.add(clearButton);
+			JButton undoButton =  new JButton("Undo");
+			undoButton.setToolTipText("One Algo Step Back.");
+			undoButton.addActionListener(actionEvent -> resetLast());
+			buttonPanel.add(undoButton);
+			JButton runButton =  new JButton("Run");
+			runButton.addActionListener(actionEvent -> {
+				Runnable task = () -> run();
+				runThread = new Thread(task);
+				runThread.start();
+			});
+			buttonPanel.add(runButton);
+			return buttonPanel;
+		}
+		private void cancel() {
+			if(runThread.isAlive()) {
+				println("");
+				println("Cancel run.");
+				cancel = true;
+				progressBar.setValue(0);
+			} else {
+				println("Nothing to cancel.");
+			}
+		}
+		
+		private void run() {
+			cancel = false;
+			disableGuiInput(true);
+			executeAlgoWithParameter();
+			updateVisual();
+			disableGuiInput(false);
+		}
+		
+		private void resetLast() {
+			if(!resetChain.isEmpty()) {
+				println("Resetting..");
+				resetState();
+				resetChain.removeLast();
+				control.resetSimulation();
+				updateVisual();
+			}else {
+				println("No run inistialized.");
+			}
+		}
+		
+		private void resetAll() {
+			if(!resetChain.isEmpty()) {
+				println("Resetting..");
+				setState(resetChain.getFirst());
+				resetChain.clear();
+				control.resetSimulation();
+				control.setCurIteration(0);
+				updateVisual();
+			}else {
+				println("No run inistialized.");
+			}
+		}
+		
+		
+		
+		private void disableGuiInput(boolean bool) {
+			control.guiDiable(bool);
+		}
+		
+		
+
+		
+		
+		@Override
+		public JPanel getAlgorithmPanel() {
+			return content;
+		}
+		@Override
+		public void setController(Control control) {
+			this.control = control;
+			
+		}
+		private void clear() {
+			textArea.setText("");
+		}
+		private void println(String message) {
+			textArea.append(message  + "\n");
+		}
+		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) {
+				println("Selected: " + selected);
+				dGroupNode = selected.object;
+			}
+		}
+		private void progressBarStep(){
+			progressBar.setValue(++progressBarCount);
+		}
+		private void calculateProgressBarParameter() {
+			int max = this.maxGenerations * this.popsize * this.rounds;
+			progressBarCount = 0;
+			progressBar.setValue(0);
+			progressBar.setMaximum(max);
+		}
+		
+		private void startTimer(){
+			startTime = System.currentTimeMillis();
+		}
+		private void printElapsedTime(){
+			long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
+			println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds);
+		}
+		
+		
+		
+		
+		private void executeAlgoWithParameter(){
+			
+			
+			
+			int actualIteration = control.getModel().getCurIteration();
+			println("TimeStep:" + actualIteration);
+			calculateProgressBarParameter();
+			
+			startTimer();
+			Individual runBest = new Individual();
+			runBest.fitness = Double.MAX_VALUE;
+			for(int r = 0; r < rounds; r++)
+			{		
+			  Individual  roundBest = executeGaAlgo();
+			  if(cancel)return;
+			  resetState();
+			  if(roundBest.fitness < runBest.fitness) runBest = roundBest;
+			}
+			printElapsedTime();
+			setState(runBest.position);
+			updateVisual();
+			println("AlgoResult:" + runBest.fitness);
+			
+			
+		}
+		
+		
+		
+		
+		//Algo Part:
+		/** 	
+		 * 	Algorithm 20 !! Fitness is better when smaller.: 
+		 *  PseudoCode:
+		 *  Best <- actual;
+		 * 	population = initPopulationRandom();
+		 * 	for(maxGeneration times){
+		 * 		for(each Individual i from population){
+		 * 			fitness <- evaluatePosition(i);
+		 * 			if(fitness < best.fitnessValue) Best <- i;
+		 * 		}
+		 * 		childList <- {};
+		 * 		for(popsize/2 times){
+		 * 			parentA <- selectAParent(population);
+		 * 			parentB <- selectAParent(population);
+		 * 			childA,childB <- crossover(Copy(parentA ), Copy(parentB));
+		 * 			mutate(childA);
+		 * 			mutate(childB);
+		 * 			childList.add(childA);
+		 * 			childList.add(childB);
+		 * 		}
+		 * 		population = childList;	
+		 * 
+		 * 	}
+		 * @return 
+		 */
+		private Individual executeGaAlgo() {
+			Individual best = new Individual();
+			best.position = extractPositionAndAccess();
+			best.fitness = evaluatePosition(best.position, false);
+			println("Start with Fitness: " + best.fitness);
+			int problemSize = best.position.size();
+			List<Individual> population = initPopuluationRandom(problemSize);
+			println("Size To Test:" + population.size());
+			for(int generation = 0; generation< maxGenerations; generation++) {
+				println("Generation" + generation + " start with Fitness: " + best.fitness);
+				for(Individual i : population) {
+					i.fitness = evaluatePosition(i.position, true);
+					println("Fitness" + i.fitness);
+					if(i.fitness < best.fitness) best = i;
+					
+				}
+				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);
+					mutate(childA, problemSize);
+					mutate(childB, problemSize);
+					childList.add(childA);
+					childList.add(childB);
+				}
+				population = childList;
+				println("________________");
+			}
+			
+			
+			println("RoundResult:" + 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 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));
+			for(int i = 2 ; i <= tournamentSize; i++) {
+				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){
+			List<Individual> population =  new ArrayList<Individual>();
+			for(int i = 0; i < popsize; i++) {
+				population.add(createRandomIndividualWithoutFitness(problemSize));
+			}
+			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;
+		}
+		/**
+		 * 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
+		 */
+		private List<Boolean> extractPositionAndAccess() {
+			Model model = control.getModel();
+			switchList = new ArrayList<HolonSwitch>();
+			objectList = new ArrayList<HolonObject>();
+			initialState = new ArrayList<Boolean>();
+			access= new HashMap<Integer, AccessWrapper>();
+			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.put(positionToInit.size() - 1 , new AccessWrapper(hE));
+					}
+					objectList.add((HolonObject) aCps);
+				}
+				else if (aCps instanceof HolonSwitch) {
+					HolonSwitch sw = (HolonSwitch) aCps;
+					positionToInit.add(sw.getState(timeStep));
+					switchList.add(sw);
+					access.put(positionToInit.size() - 1 , new AccessWrapper(sw));
+				}
+				else if(aCps instanceof CpsUpperNode) {
+					rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit ,timeStep );
+				}
+			}
+		}
+		
+		
+		
+		private double evaluatePosition(List<Boolean> position, boolean doIncreaseCounter) {
+			setState(position);
+			if(doIncreaseCounter)progressBarStep();
+			control.calculateStateOnlyForCurrentTimeStep();
+			DecoratedState actualstate = control.getSimManager().getActualDecorState();		
+			return PSOAlgorithm.getFitnessValueForState(actualstate);
+		}
+		
+		
+		
+		/**
+		 * To let the User See the current state without touching the Canvas.
+		 */
+		private void updateVisual() {
+			control.calculateStateAndVisualForCurrentTimeStep();
+			//control.updateCanvas();
+			//control.getGui().triggerUpdateController(null);
+		}
+		/**
+		 * 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) {
+			for(int i = 0;i<position.size();i++) {
+				access.get(i).setState(position.get(i));
+			}
+		}
+		
+		private class Individual {
+			public double fitness;
+			public  List<Boolean> position;
+			
+			Individual(){};
+			/**
+			 *  Copy Constructor
+			 */
+			Individual(Individual c){
+				position = c.position.stream().collect(Collectors.toList());
+				fitness = c.fitness;
+			}
+		}
+		
+		
+		
+		
+		
+		
+		
+		/**
+		 * 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;
+			}
+		}
+		
+		
+		private class RunResult {
+			public int activatedFlex = 0;
+			public int deactivatedElements = 0;
+			public float totalCost = 0;
+			public LinkedList<TimeStepStateResult> timeStepList = new LinkedList<TimeStepStateResult>();
+			
+			
+			public TimeStepStateResult addTimeStepStateResult(){
+				TimeStepStateResult aResult = new TimeStepStateResult();
+				timeStepList.add(aResult);
+				return aResult;
+			}
+			
+			
+			public class TimeStepStateResult{
+				public int amountOfProducer = 0;
+				public int amountOfConsumer = 0;
+				public int amountOfPassiv = 0;
+				public int amountOfConsumerOverSupplied = 0;
+				public int amountOfConsumerSupplied = 0;
+				public int amountOfConsumerPartiallySupplied = 0;
+				public int amountOfConsumerUnSupplied= 0;
+				
+				public float getProportionWithState(HolonObjectState state) {
+					float amountOfObjects = amountOfProducer + amountOfConsumer + amountOfPassiv;
+					switch(state) {
+					case NOT_SUPPLIED:
+						return (float) amountOfConsumerUnSupplied / amountOfObjects;
+					case NO_ENERGY:
+						return (float) amountOfPassiv / amountOfObjects;
+					case OVER_SUPPLIED:
+						return (float) amountOfConsumerOverSupplied / amountOfObjects;
+					case PARTIALLY_SUPPLIED:
+						return (float) amountOfConsumerPartiallySupplied / amountOfObjects;
+					case PRODUCER:
+						return (float) amountOfProducer / amountOfObjects;
+					case SUPPLIED:
+						return (float) amountOfConsumerSupplied / amountOfObjects;
+					default:
+						return 0.f;
+					}
+				}
+			}
+			public float getAvergaeProportionWithState(HolonObjectState state) {
+				return timeStepList.stream().map(step -> step.getProportionWithState(state)).reduce((a,b) -> (a + b)).orElse(0.f) / (float) 100;
+			}
+		}
+		
+
+		/**
+		* To create Random and maybe switch the random generation in the future.
+		*/
+		private 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();
+			}
+		}
+
+}

+ 12 - 9
src/exampleAlgorithms/PSOAlgotihm.java → src/exampleAlgorithms/PSOAlgorithm.java

@@ -54,14 +54,14 @@ import ui.model.DecoratedState;
 
 
 
-public class PSOAlgotihm implements Algorithm {
+public class PSOAlgorithm implements Algorithm {
 	//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 rounds = 20;
-	private int mutationInterval = 0;
+	private int mutationInterval = 1;
 	
 	//Settings For GroupNode using and plotting
 	private boolean append = false;
@@ -94,13 +94,13 @@ public class PSOAlgotihm implements Algorithm {
 	public static void main(String[] args)
 	{
 	      JFrame newFrame = new JFrame("exampleWindow");
-	      PSOAlgotihm instance = new PSOAlgotihm();
+	      PSOAlgorithm instance = new PSOAlgorithm();
 	      newFrame.setContentPane(instance.getAlgorithmPanel());
 	      newFrame.pack();
 	      newFrame.setVisible(true);
 	      newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 	}
-	public PSOAlgotihm() {
+	public PSOAlgorithm() {
 		content.setLayout(new BorderLayout());
 	
 		textArea = new JTextArea();
@@ -277,7 +277,10 @@ public class PSOAlgotihm implements Algorithm {
 		mutationIntervalFormatter.setMaximum(maxIterations);
 		mutationIntervalFormatter.setCommitsOnValidEdit(true);*/
 		
-		JFormattedTextField mutationIntervalTextfield = new JFormattedTextField(integerFormatter);
+		NumberFormatter mutationFormatter = new NumberFormatter(format);
+		mutationFormatter.setMinimum(1);
+		mutationFormatter.setCommitsOnValidEdit(true);
+		JFormattedTextField mutationIntervalTextfield = new JFormattedTextField(mutationFormatter);
 		mutationIntervalTextfield.setValue(mutationInterval);
 		mutationIntervalTextfield.setToolTipText("The number of Iterations after which one mutation iteration is conducted");
 		mutationIntervalTextfield.addPropertyChangeListener(propertyChange -> mutationInterval = Integer.parseInt((mutationIntervalTextfield.getValue().toString())));
@@ -627,7 +630,7 @@ public class PSOAlgotihm implements Algorithm {
 	 * @param state
 	 * @return
 	 */
-	private double getFitnessValueForState(DecoratedState state) {
+	public static double getFitnessValueForState(DecoratedState state) {
 		double fitness = 0.0;
 		double nw_fitness =0.0;
 		double object_fitness = 0.0;
@@ -661,7 +664,7 @@ public class PSOAlgotihm implements Algorithm {
 	 * @param obj Holon Object that contains Holon Elements
 	 * @return fitness value for that object depending on the number of deactivated holon elements
 	 */
-	private double inactiveHolonElementPenalty(HolonObject obj) {
+	private static double inactiveHolonElementPenalty(HolonObject obj) {
 		float result = 0;
 		int activeElements = obj.getNumberOfActiveElements();
 		int maxElements = obj.getElements().size();
@@ -678,7 +681,7 @@ public class PSOAlgotihm implements Algorithm {
 	 * @param supplyPercentage
 	 * @return
 	 */
-	private double holonObjectSupplyPenaltyFunction(float supplyPercentage) {
+	private static double holonObjectSupplyPenaltyFunction(float supplyPercentage) {
 		double result = 0;
 		/*if(supplyPercentage == 1)
 			return result;
@@ -708,7 +711,7 @@ public class PSOAlgotihm implements Algorithm {
 	 * @param state
 	 * @return
 	 */
-	private double StateToDouble(HolonObjectState state) {
+	private static double StateToDouble(HolonObjectState state) {
 		switch (state) {
 		case NOT_SUPPLIED:
 			return 150.0;