Browse Source

Gen Algo Integriert und basic funktionalität

Dominik Rieder 5 years ago
parent
commit
8e2132aad7

+ 394 - 0
src/algorithms/AlgoWindow.java

@@ -0,0 +1,394 @@
+package algorithms;
+
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+
+import ui.controller.Control;
+import ui.model.Model;
+import algorithms.GeneticAlgorithm.GenAlgoHandler;
+import algorithms.GeneticAlgorithm.HolegGeneration;
+import algorithms.GeneticAlgorithm.HolegIndividual;
+import algorithms.GeneticAlgorithm.ParameterArray;
+
+public class AlgoWindow {
+	JPanel frame;
+	Control controller;
+	Model model;
+	JTree genTree;
+	DefaultTreeModel treeModel;
+	DefaultMutableTreeNode treeRoot;
+	HashMap<DefaultMutableTreeNode, HolegIndividual> treeIndiHashmap;
+	GenAlgoHandler algoHandler;
+	ArrayList<DefaultMutableTreeNode> generationNodes = new ArrayList<DefaultMutableTreeNode>();
+	private JTextField edgeAmountField;
+	private JCheckBox chckbxEditEdges;
+	private JTextArea logArea;
+	private JTextField popSizeField;
+	private JTextField tournamentSizeField;
+	private JTextField edgeBreakCount;
+	private JTextField iterationsField;
+	ParameterArray params;
+	private JTextField edgeMutationField;
+	private JTextField suppliedField;
+	private JTextField oversuppliedField;
+	private JTextField undersuppliedField;
+	private JTextField edgeLengthField;
+	private JTextField wildcardUsageField;
+	private JTextField wildcardMutationField;
+	private JTextField partialSuppliedField;
+	private JTextField overproductionField;
+	private JTextField generationAmountField;
+	private JCheckBox chckbxWildNodes;
+	ArrayList<HolegGeneration> generationHistory = new ArrayList<HolegGeneration>();
+	/**
+	 * Create the application.
+	 */
+	public AlgoWindow(Control controller, Model model) {
+		this.model = model;
+		this.controller = controller;
+		//algoHandler = new GenAlgoHandler(controller, model);
+		//algoHandler.addListener(this);
+
+		treeIndiHashmap = new HashMap<DefaultMutableTreeNode, HolegIndividual>();
+		initialize();
+		algoHandler.setOriginalNetwork();
+		
+	}
+
+	/**
+	 * Initialize the contents of the frame.
+	 */
+	private void initialize() {
+		frame = new JPanel();
+		frame.setBounds(100, 100, 444, 500);
+		frame.setLayout(new BoxLayout(frame, BoxLayout.X_AXIS));
+		
+	
+		JSplitPane mainSplitPane = new JSplitPane();
+		mainSplitPane.setResizeWeight(0.3);
+		frame.add(mainSplitPane);
+		
+		JScrollPane treeScrollPane = new JScrollPane();
+		mainSplitPane.setLeftComponent(treeScrollPane);
+		
+		genTree = new JTree();
+		treeScrollPane.setViewportView(genTree);
+		
+		treeModel = (DefaultTreeModel) genTree.getModel();
+		treeRoot = new DefaultMutableTreeNode("Generations");
+		treeModel.setRoot(treeRoot);
+		genTree.setModel(treeModel);
+		
+		JSplitPane rightSplitPane = new JSplitPane();
+		rightSplitPane.setResizeWeight(0.7);
+		rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
+		mainSplitPane.setRightComponent(rightSplitPane);
+		
+		JPanel parameterPanel = new JPanel();
+		parameterPanel.setPreferredSize(new Dimension(100, 650));
+		JScrollPane parameterScrollView = new JScrollPane();
+		rightSplitPane.setLeftComponent(parameterScrollView);
+		parameterScrollView.setViewportView(parameterPanel);
+
+		
+		JButton btnCreategeneration = new JButton("create N Generations");
+		btnCreategeneration.setBounds(10, 11, 137, 23);
+		btnCreategeneration.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				setParameters();
+				algoHandler.createGeneration(Integer.parseInt(generationAmountField.getText()), params);
+			}
+		});
+		parameterPanel.setLayout(null);
+		parameterPanel.add(btnCreategeneration);
+		
+		edgeAmountField = new JTextField();
+		edgeAmountField.setText("0");
+		edgeAmountField.setBounds(147, 119, 86, 20);
+		parameterPanel.add(edgeAmountField);
+		edgeAmountField.setColumns(10);
+		
+		JLabel lblMaxEdges = new JLabel("Max Edges");
+		lblMaxEdges.setBounds(10, 122, 91, 14);
+		parameterPanel.add(lblMaxEdges);
+		
+		chckbxEditEdges = new JCheckBox("\r\n");
+		chckbxEditEdges.setBounds(147, 92, 25, 23);
+		parameterPanel.add(chckbxEditEdges);
+		
+		JLabel lblEditEdges = new JLabel("Edit Edges?");
+		lblEditEdges.setBounds(10, 96, 91, 14);
+		parameterPanel.add(lblEditEdges);
+		
+		popSizeField = new JTextField();
+		popSizeField.setText("100");
+		popSizeField.setBounds(147, 45, 86, 20);
+		parameterPanel.add(popSizeField);
+		popSizeField.setColumns(10);
+		
+		tournamentSizeField = new JTextField();
+		tournamentSizeField.setText("30");
+		tournamentSizeField.setBounds(147, 70, 86, 20);
+		parameterPanel.add(tournamentSizeField);
+		tournamentSizeField.setColumns(10);
+		
+		JLabel lblPopulationSize = new JLabel("Population Size");
+		lblPopulationSize.setBounds(10, 45, 91, 14);
+		parameterPanel.add(lblPopulationSize);
+		
+		JLabel lblTournamentSize = new JLabel("Tournament Size");
+		lblTournamentSize.setBounds(10, 73, 91, 14);
+		parameterPanel.add(lblTournamentSize);
+		
+		edgeBreakCount = new JTextField();
+		edgeBreakCount.setText("0");
+		edgeBreakCount.setBounds(147, 144, 86, 20);
+		parameterPanel.add(edgeBreakCount);
+		edgeBreakCount.setColumns(10);
+		
+		JLabel lblEdgeBreakProb = new JLabel("Edge Break Amount");
+		lblEdgeBreakProb.setBounds(10, 147, 117, 14);
+		parameterPanel.add(lblEdgeBreakProb);
+		
+		iterationsField = new JTextField();
+		iterationsField.setText("1");
+		iterationsField.setBounds(147, 169, 86, 20);
+		parameterPanel.add(iterationsField);
+		iterationsField.setColumns(10);
+		
+		JLabel lblSimIteration = new JLabel("Sim Iterations");
+		lblSimIteration.setBounds(10, 172, 91, 14);
+		parameterPanel.add(lblSimIteration);
+		
+		edgeMutationField = new JTextField();
+		edgeMutationField.setText("0.01");
+		edgeMutationField.setBounds(147, 194, 86, 20);
+		parameterPanel.add(edgeMutationField);
+		edgeMutationField.setColumns(10);
+		
+		JLabel lblMutationProb = new JLabel("Edge Mutation Prob");
+		lblMutationProb.setBounds(10, 197, 117, 14);
+		parameterPanel.add(lblMutationProb);
+		
+		suppliedField = new JTextField();
+		suppliedField.setText("+10.0");
+		suppliedField.setBounds(147, 297, 86, 20);
+		parameterPanel.add(suppliedField);
+		suppliedField.setColumns(10);
+		
+		JLabel lblFittnesspointsPerAttribute = new JLabel("Fittnesspoints per Attribute:");
+		lblFittnesspointsPerAttribute.setFont(new Font("Tahoma", Font.PLAIN, 12));
+		lblFittnesspointsPerAttribute.setBounds(59, 275, 157, 14);
+		parameterPanel.add(lblFittnesspointsPerAttribute);
+		
+		JLabel lblSuppliedEntity = new JLabel("each supplied Entity");
+		lblSuppliedEntity.setBounds(10, 300, 117, 14);
+		parameterPanel.add(lblSuppliedEntity);
+		
+		oversuppliedField = new JTextField();
+		oversuppliedField.setText("+10.0");
+		oversuppliedField.setBounds(147, 322, 86, 20);
+		parameterPanel.add(oversuppliedField);
+		oversuppliedField.setColumns(10);
+		
+		JLabel lblOversuppliedEntity = new JLabel("each oversupplied Entity");
+		lblOversuppliedEntity.setBounds(10, 325, 127, 14);
+		parameterPanel.add(lblOversuppliedEntity);
+		
+		undersuppliedField = new JTextField();
+		undersuppliedField.setText("-10.0");
+		undersuppliedField.setBounds(147, 347, 86, 20);
+		parameterPanel.add(undersuppliedField);
+		undersuppliedField.setColumns(10);
+		
+		JLabel lblEachUndersuppliedEntity = new JLabel("each undersupplied Entity");
+		lblEachUndersuppliedEntity.setBounds(10, 350, 127, 14);
+		parameterPanel.add(lblEachUndersuppliedEntity);
+		
+		edgeLengthField = new JTextField();
+		edgeLengthField.setText("-1.0");
+		edgeLengthField.setBounds(147, 397, 86, 20);
+		parameterPanel.add(edgeLengthField);
+		edgeLengthField.setColumns(10);
+		
+		JLabel lblForEdge = new JLabel("for 100 edge length");
+		lblForEdge.setBounds(10, 400, 127, 14);
+		parameterPanel.add(lblForEdge);
+		
+		wildcardUsageField = new JTextField();
+		wildcardUsageField.setText("-7.0");
+		wildcardUsageField.setBounds(147, 422, 86, 20);
+		parameterPanel.add(wildcardUsageField);
+		wildcardUsageField.setColumns(10);
+		
+		JLabel lblWildcardUsage = new JLabel("each Wildcard usage");
+		lblWildcardUsage.setBounds(10, 425, 127, 14);
+		parameterPanel.add(lblWildcardUsage);
+		
+		JLabel lblWildcardMutation = new JLabel("Wildcard Mutation Prob");
+		lblWildcardMutation.setBounds(10, 222, 117, 14);
+		parameterPanel.add(lblWildcardMutation);
+		
+		wildcardMutationField = new JTextField();
+		wildcardMutationField.setText("0.01");
+		wildcardMutationField.setBounds(147, 219, 86, 20);
+		parameterPanel.add(wildcardMutationField);
+		wildcardMutationField.setColumns(10);
+		
+		JLabel lblEachPartiallySupplied = new JLabel("each partialsupplied Entity");
+		lblEachPartiallySupplied.setBounds(10, 375, 137, 14);
+		parameterPanel.add(lblEachPartiallySupplied);
+		
+		partialSuppliedField = new JTextField();
+		partialSuppliedField.setText("-2.0");
+		partialSuppliedField.setBounds(147, 372, 86, 20);
+		parameterPanel.add(partialSuppliedField);
+		partialSuppliedField.setColumns(10);
+		
+		JLabel lblForOverproduction = new JLabel("for 1000 overproduction");
+		lblForOverproduction.setBounds(10, 450, 117, 14);
+		parameterPanel.add(lblForOverproduction);
+		
+		overproductionField = new JTextField();
+		overproductionField.setText("-5.0");
+		overproductionField.setBounds(147, 447, 86, 20);
+		parameterPanel.add(overproductionField);
+		overproductionField.setColumns(10);
+		
+		generationAmountField = new JTextField();
+		generationAmountField.setText("1");
+		generationAmountField.setBounds(147, 12, 86, 20);
+		parameterPanel.add(generationAmountField);
+		generationAmountField.setColumns(10);
+		
+		JLabel lblNodesInWildcards = new JLabel("Nodes in Wildcards?");
+		lblNodesInWildcards.setBounds(10, 247, 117, 14);
+		parameterPanel.add(lblNodesInWildcards);
+		
+		chckbxWildNodes = new JCheckBox("");
+		chckbxWildNodes.setBounds(147, 245, 97, 20);
+		parameterPanel.add(chckbxWildNodes);
+		
+		logArea = new JTextArea();
+		rightSplitPane.setRightComponent(logArea);
+		
+		 MouseListener ml = new MouseAdapter() {
+		     public void mousePressed(MouseEvent e) {
+		         int selRow = genTree.getRowForLocation(e.getX(), e.getY());
+		         TreePath selPath = genTree.getPathForLocation(e.getX(), e.getY());
+		         if(selRow != -1) {
+		             if(e.getClickCount() == 1) {
+		                 nodeSingleClick(selRow, selPath);
+		             }
+		             else if(e.getClickCount() == 2) {
+		                 nodeDoubleClick(selRow, selPath);
+		             }
+		         }
+		     }
+		 };
+		 genTree.addMouseListener(ml);
+		
+	}
+	
+	public void nodeSingleClick(int selRow, TreePath selPath){
+		DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
+	
+		if(node.getUserObject() instanceof HolegGeneration){
+			logArea.setText(((HolegGeneration)node.getUserObject()).getInformation());
+		}
+	}
+	
+	public void nodeDoubleClick(int selRow, TreePath selPath){
+		DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
+		
+	
+		if(treeIndiHashmap.get(node) != null){
+			algoHandler.drawIndividualWithPos(treeIndiHashmap.get(node));
+			logArea.setText(treeIndiHashmap.get(node).log);
+		}
+	
+	}
+	
+
+
+	public void populationCreated(HolegGeneration holegGen) {
+		DefaultMutableTreeNode genNode = new DefaultMutableTreeNode(holegGen);
+		generationHistory.add(holegGen);
+		ArrayList<HolegIndividual> population = holegGen.getGeneration();
+		for(int i = 0; i < population.size(); i++){
+			DefaultMutableTreeNode child = new DefaultMutableTreeNode("Individual " + i);
+			population.get(i).setId(holegGen.getGenCount(), i);
+			treeIndiHashmap.put(child, population.get(i));
+			genNode.add(child);
+		}
+		generationNodes.add(genNode);
+		treeRoot.insert(genNode, 0);
+		treeModel.reload();	
+		if(holegGen.getGenCount() == HolegGeneration.ORIGINAL_GEN){
+			int nodeAmount = holegGen.getGeneration().get(0).getIndexes().size();
+			int maxEdges = (nodeAmount*(nodeAmount-1))/2;
+			edgeAmountField.setText(Integer.toString(maxEdges));
+
+			params.set(params.ORIGINAL_NETWORK, holegGen.getGeneration().get(0));
+		}
+	}
+
+	
+	
+	
+	/**
+	 * sets All Parameters from the Textfields into the ParameterArray;
+	 */
+	public void setParameters(){
+		params.set(params.MAX_EDGES, Integer.parseInt(edgeAmountField.getText()));
+		params.set(params.EDIT_EDGES, chckbxEditEdges.isSelected());
+		params.set(params.POPULATION_SIZE, Integer.parseInt(popSizeField.getText()));
+		params.set(params.TOURNAMENT_SIZE, Integer.parseInt(tournamentSizeField.getText()));
+		params.set(params.EDGE_BREAK_AMOUNT, Integer.parseInt(edgeBreakCount.getText()));
+		params.set(params.SIM_ITERATIONS, Integer.parseInt(iterationsField.getText()));
+		params.set(params.EDGE_MUTATION_PROB, Double.parseDouble(edgeMutationField.getText()));
+		params.set(params.SUPPLIED_POINTS, Double.parseDouble(suppliedField.getText()));
+		params.set(params.OVERSUPPLIED_POINTS, Double.parseDouble(oversuppliedField.getText()));
+		params.set(params.UNDERSUPPLIED_POINTS, Double.parseDouble(undersuppliedField.getText()));
+		params.set(params.LENGTH_POINTS, Double.parseDouble(edgeLengthField.getText()));
+		params.set(params.WILDCARD_USAGE, Double.parseDouble(wildcardUsageField.getText()));
+		params.set(params.WILDCARD_MUTATION_PROB, Double.parseDouble(wildcardMutationField.getText()));
+		params.set(params.PARTIALSUPPLIED_POINTS, Double.parseDouble(partialSuppliedField.getText()));
+		params.set(params.OVERPRODUCTION, Double.parseDouble(overproductionField.getText()));	
+		params.set(params.NODES_IN_WILDCARDS, chckbxWildNodes.isSelected());
+		params.set(params.TOURNAMENT_PROB, 0.15);
+	}
+	
+	public ArrayList<HolegGeneration> evaluationRun(ParameterArray params){
+		generationHistory = new ArrayList<HolegGeneration>();
+		params.set(params.ORIGINAL_NETWORK, this.params.get(params.ORIGINAL_NETWORK));
+		algoHandler.createGeneration(100, params);
+		return generationHistory;
+		
+	}
+	
+	public void setEvalParameters(ParameterArray params){
+		this.params = params;
+	}
+}

+ 1947 - 0
src/algorithms/GeneticAlgorithm.java

@@ -0,0 +1,1947 @@
+package algorithms;
+
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Random;
+import java.util.Set;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+
+import classes.AbstractCpsObject;
+import classes.Category;
+import classes.CpsEdge;
+import classes.CpsNode;
+import classes.HolonBattery;
+import classes.HolonObject;
+import classes.HolonSwitch;
+import classes.IdCounter;
+import classes.Position;
+import ui.controller.Control;
+import ui.controller.SimulationManager;
+import ui.model.DecoratedHolonObject.HolonObjectState;
+import ui.model.DecoratedNetwork;
+import ui.model.DecoratedState;
+import ui.model.Model;
+import api.Algorithm;
+
+public class GeneticAlgorithm implements Algorithm {
+	Control controller;
+	
+	@Override
+	public JPanel getAlgorithmPanel() {
+		GenAlgoWindow panel = new GenAlgoWindow(controller, controller.getModel());
+		return panel.frame;
+	}
+
+	@Override
+	public void setController(Control control) {
+		controller = control;
+	}
+	/*
+	 * The Window of the Algorithm
+	 */
+	public class GenAlgoWindow {
+		JPanel frame;
+		Control controller;
+		Model model;
+		JTree genTree;
+		DefaultTreeModel treeModel;
+		DefaultMutableTreeNode treeRoot;
+		HashMap<DefaultMutableTreeNode, HolegIndividual> treeIndiHashmap;
+		GenAlgoHandler algoHandler;
+		ArrayList<DefaultMutableTreeNode> generationNodes = new ArrayList<DefaultMutableTreeNode>();
+		private JTextField edgeAmountField;
+		private JCheckBox chckbxEditEdges;
+		private JTextArea logArea;
+		private JTextField popSizeField;
+		private JTextField tournamentSizeField;
+		private JTextField edgeBreakCount;
+		private JTextField iterationsField;
+		ParameterArray params = new ParameterArray();
+		private JTextField edgeMutationField;
+		private JTextField suppliedField;
+		private JTextField oversuppliedField;
+		private JTextField undersuppliedField;
+		private JTextField edgeLengthField;
+		private JTextField wildcardUsageField;
+		private JTextField wildcardMutationField;
+		private JTextField partialSuppliedField;
+		private JTextField overproductionField;
+		private JTextField generationAmountField;
+		private JCheckBox chckbxWildNodes;
+		ArrayList<HolegGeneration> generationHistory = new ArrayList<HolegGeneration>();
+		/**
+		 * Create the application.
+		 */
+		public GenAlgoWindow(Control controller, Model model) {
+			this.model = model;
+			this.controller = controller;
+			algoHandler = new GenAlgoHandler(controller, model);
+			algoHandler.addListener(this);
+			treeIndiHashmap = new HashMap<DefaultMutableTreeNode, HolegIndividual>();
+			initialize();
+			algoHandler.setOriginalNetwork();
+			
+		}
+
+		/**
+		 * Initialize the contents of the frame.
+		 */
+		private void initialize() {
+			frame = new JPanel();
+			//frame.setBounds(100, 100, 500, 500);
+			frame.setPreferredSize(new Dimension(500, 500));
+			frame.setLayout(new BoxLayout(frame, BoxLayout.X_AXIS));
+			
+		
+			JSplitPane mainSplitPane = new JSplitPane();
+			mainSplitPane.setResizeWeight(0.3);
+			frame.add(mainSplitPane);
+			
+			JScrollPane treeScrollPane = new JScrollPane();
+			mainSplitPane.setLeftComponent(treeScrollPane);
+			
+			genTree = new JTree();
+			treeScrollPane.setViewportView(genTree);
+			
+			treeModel = (DefaultTreeModel) genTree.getModel();
+			treeRoot = new DefaultMutableTreeNode("Generations");
+			treeModel.setRoot(treeRoot);
+			genTree.setModel(treeModel);
+			
+			JSplitPane rightSplitPane = new JSplitPane();
+			rightSplitPane.setResizeWeight(0.7);
+			rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
+			mainSplitPane.setRightComponent(rightSplitPane);
+			
+			JPanel parameterPanel = new JPanel();
+			parameterPanel.setPreferredSize(new Dimension(100, 650));
+			JScrollPane parameterScrollView = new JScrollPane();
+			rightSplitPane.setLeftComponent(parameterScrollView);
+			parameterScrollView.setViewportView(parameterPanel);
+
+			
+			JButton btnCreategeneration = new JButton("create N Generations");
+			btnCreategeneration.setBounds(10, 11, 137, 23);
+			btnCreategeneration.addActionListener(new ActionListener() {
+				public void actionPerformed(ActionEvent arg0) {
+					setParameters();
+					algoHandler.createGeneration(Integer.parseInt(generationAmountField.getText()), params);
+				}
+			});
+			parameterPanel.setLayout(null);
+			parameterPanel.add(btnCreategeneration);
+			
+			edgeAmountField = new JTextField();
+			edgeAmountField.setText("0");
+			edgeAmountField.setBounds(147, 119, 86, 20);
+			parameterPanel.add(edgeAmountField);
+			edgeAmountField.setColumns(10);
+			
+			JLabel lblMaxEdges = new JLabel("Max Edges");
+			lblMaxEdges.setBounds(10, 122, 91, 14);
+			parameterPanel.add(lblMaxEdges);
+			
+			chckbxEditEdges = new JCheckBox("\r\n");
+			chckbxEditEdges.setBounds(147, 92, 25, 23);
+			parameterPanel.add(chckbxEditEdges);
+			
+			JLabel lblEditEdges = new JLabel("Edit Edges?");
+			lblEditEdges.setBounds(10, 96, 91, 14);
+			parameterPanel.add(lblEditEdges);
+			
+			popSizeField = new JTextField();
+			popSizeField.setText("100");
+			popSizeField.setBounds(147, 45, 86, 20);
+			parameterPanel.add(popSizeField);
+			popSizeField.setColumns(10);
+			
+			tournamentSizeField = new JTextField();
+			tournamentSizeField.setText("30");
+			tournamentSizeField.setBounds(147, 70, 86, 20);
+			parameterPanel.add(tournamentSizeField);
+			tournamentSizeField.setColumns(10);
+			
+			JLabel lblPopulationSize = new JLabel("Population Size");
+			lblPopulationSize.setBounds(10, 45, 91, 14);
+			parameterPanel.add(lblPopulationSize);
+			
+			JLabel lblTournamentSize = new JLabel("Tournament Size");
+			lblTournamentSize.setBounds(10, 73, 91, 14);
+			parameterPanel.add(lblTournamentSize);
+			
+			edgeBreakCount = new JTextField();
+			edgeBreakCount.setText("0");
+			edgeBreakCount.setBounds(147, 144, 86, 20);
+			parameterPanel.add(edgeBreakCount);
+			edgeBreakCount.setColumns(10);
+			
+			JLabel lblEdgeBreakProb = new JLabel("Edge Break Amount");
+			lblEdgeBreakProb.setBounds(10, 147, 117, 14);
+			parameterPanel.add(lblEdgeBreakProb);
+			
+			iterationsField = new JTextField();
+			iterationsField.setText("1");
+			iterationsField.setBounds(147, 169, 86, 20);
+			parameterPanel.add(iterationsField);
+			iterationsField.setColumns(10);
+			
+			JLabel lblSimIteration = new JLabel("Sim Iterations");
+			lblSimIteration.setBounds(10, 172, 91, 14);
+			parameterPanel.add(lblSimIteration);
+			
+			edgeMutationField = new JTextField();
+			edgeMutationField.setText("0.01");
+			edgeMutationField.setBounds(147, 194, 86, 20);
+			parameterPanel.add(edgeMutationField);
+			edgeMutationField.setColumns(10);
+			
+			JLabel lblMutationProb = new JLabel("Edge Mutation Prob");
+			lblMutationProb.setBounds(10, 197, 117, 14);
+			parameterPanel.add(lblMutationProb);
+			
+			suppliedField = new JTextField();
+			suppliedField.setText("+10.0");
+			suppliedField.setBounds(147, 297, 86, 20);
+			parameterPanel.add(suppliedField);
+			suppliedField.setColumns(10);
+			
+			JLabel lblFittnesspointsPerAttribute = new JLabel("Fittnesspoints per Attribute:");
+			lblFittnesspointsPerAttribute.setFont(new Font("Tahoma", Font.PLAIN, 12));
+			lblFittnesspointsPerAttribute.setBounds(59, 275, 157, 14);
+			parameterPanel.add(lblFittnesspointsPerAttribute);
+			
+			JLabel lblSuppliedEntity = new JLabel("each supplied Entity");
+			lblSuppliedEntity.setBounds(10, 300, 117, 14);
+			parameterPanel.add(lblSuppliedEntity);
+			
+			oversuppliedField = new JTextField();
+			oversuppliedField.setText("+10.0");
+			oversuppliedField.setBounds(147, 322, 86, 20);
+			parameterPanel.add(oversuppliedField);
+			oversuppliedField.setColumns(10);
+			
+			JLabel lblOversuppliedEntity = new JLabel("each oversupplied Entity");
+			lblOversuppliedEntity.setBounds(10, 325, 127, 14);
+			parameterPanel.add(lblOversuppliedEntity);
+			
+			undersuppliedField = new JTextField();
+			undersuppliedField.setText("-10.0");
+			undersuppliedField.setBounds(147, 347, 86, 20);
+			parameterPanel.add(undersuppliedField);
+			undersuppliedField.setColumns(10);
+			
+			JLabel lblEachUndersuppliedEntity = new JLabel("each undersupplied Entity");
+			lblEachUndersuppliedEntity.setBounds(10, 350, 127, 14);
+			parameterPanel.add(lblEachUndersuppliedEntity);
+			
+			edgeLengthField = new JTextField();
+			edgeLengthField.setText("-1.0");
+			edgeLengthField.setBounds(147, 397, 86, 20);
+			parameterPanel.add(edgeLengthField);
+			edgeLengthField.setColumns(10);
+			
+			JLabel lblForEdge = new JLabel("for 100 edge length");
+			lblForEdge.setBounds(10, 400, 127, 14);
+			parameterPanel.add(lblForEdge);
+			
+			wildcardUsageField = new JTextField();
+			wildcardUsageField.setText("-7.0");
+			wildcardUsageField.setBounds(147, 422, 86, 20);
+			parameterPanel.add(wildcardUsageField);
+			wildcardUsageField.setColumns(10);
+			
+			JLabel lblWildcardUsage = new JLabel("each Wildcard usage");
+			lblWildcardUsage.setBounds(10, 425, 127, 14);
+			parameterPanel.add(lblWildcardUsage);
+			
+			JLabel lblWildcardMutation = new JLabel("Wildcard Mutation Prob");
+			lblWildcardMutation.setBounds(10, 222, 117, 14);
+			parameterPanel.add(lblWildcardMutation);
+			
+			wildcardMutationField = new JTextField();
+			wildcardMutationField.setText("0.01");
+			wildcardMutationField.setBounds(147, 219, 86, 20);
+			parameterPanel.add(wildcardMutationField);
+			wildcardMutationField.setColumns(10);
+			
+			JLabel lblEachPartiallySupplied = new JLabel("each partialsupplied Entity");
+			lblEachPartiallySupplied.setBounds(10, 375, 137, 14);
+			parameterPanel.add(lblEachPartiallySupplied);
+			
+			partialSuppliedField = new JTextField();
+			partialSuppliedField.setText("-2.0");
+			partialSuppliedField.setBounds(147, 372, 86, 20);
+			parameterPanel.add(partialSuppliedField);
+			partialSuppliedField.setColumns(10);
+			
+			JLabel lblForOverproduction = new JLabel("for 1000 overproduction");
+			lblForOverproduction.setBounds(10, 450, 117, 14);
+			parameterPanel.add(lblForOverproduction);
+			
+			overproductionField = new JTextField();
+			overproductionField.setText("-5.0");
+			overproductionField.setBounds(147, 447, 86, 20);
+			parameterPanel.add(overproductionField);
+			overproductionField.setColumns(10);
+			
+			generationAmountField = new JTextField();
+			generationAmountField.setText("1");
+			generationAmountField.setBounds(147, 12, 86, 20);
+			parameterPanel.add(generationAmountField);
+			generationAmountField.setColumns(10);
+			
+			JLabel lblNodesInWildcards = new JLabel("Nodes in Wildcards?");
+			lblNodesInWildcards.setBounds(10, 247, 117, 14);
+			parameterPanel.add(lblNodesInWildcards);
+			
+			chckbxWildNodes = new JCheckBox("");
+			chckbxWildNodes.setBounds(147, 245, 97, 20);
+			parameterPanel.add(chckbxWildNodes);
+			
+			logArea = new JTextArea();
+			rightSplitPane.setRightComponent(logArea);
+			
+			 MouseListener ml = new MouseAdapter() {
+			     public void mousePressed(MouseEvent e) {
+			         int selRow = genTree.getRowForLocation(e.getX(), e.getY());
+			         TreePath selPath = genTree.getPathForLocation(e.getX(), e.getY());
+			         if(selRow != -1) {
+			             if(e.getClickCount() == 1) {
+			                 nodeSingleClick(selRow, selPath);
+			             }
+			             else if(e.getClickCount() == 2) {
+			                 nodeDoubleClick(selRow, selPath);
+			             }
+			         }
+			     }
+			 };
+			 genTree.addMouseListener(ml);
+			
+		}
+		
+		public void nodeSingleClick(int selRow, TreePath selPath){
+			DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
+		
+			if(node.getUserObject() instanceof HolegGeneration){
+				logArea.setText(((HolegGeneration)node.getUserObject()).getInformation());
+			}
+		}
+		
+		public void nodeDoubleClick(int selRow, TreePath selPath){
+			DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
+			
+		
+			if(treeIndiHashmap.get(node) != null){
+				algoHandler.drawIndividualWithPos(treeIndiHashmap.get(node));
+				logArea.setText(treeIndiHashmap.get(node).log);
+			}
+		
+		}
+		
+
+	
+		public void populationCreated(HolegGeneration holegGen) {
+			DefaultMutableTreeNode genNode = new DefaultMutableTreeNode(holegGen);
+			generationHistory.add(holegGen);
+			ArrayList<HolegIndividual> population = holegGen.getGeneration();
+			for(int i = 0; i < population.size(); i++){
+				DefaultMutableTreeNode child = new DefaultMutableTreeNode("Individual " + i);
+				population.get(i).setId(holegGen.getGenCount(), i);
+				treeIndiHashmap.put(child, population.get(i));
+				genNode.add(child);
+			}
+			generationNodes.add(genNode);
+			treeRoot.insert(genNode, 0);
+			treeModel.reload();	
+			if(holegGen.getGenCount() == HolegGeneration.ORIGINAL_GEN){
+				int nodeAmount = holegGen.getGeneration().get(0).getIndexes().size();
+				int maxEdges = (nodeAmount*(nodeAmount-1))/2;
+				edgeAmountField.setText(Integer.toString(maxEdges));
+
+				params.set(params.ORIGINAL_NETWORK, holegGen.getGeneration().get(0));
+			}
+		}
+	
+		
+		
+		
+		/**
+		 * sets All Parameters from the Textfields into the ParameterArray;
+		 */
+		public void setParameters(){
+			params.set(params.MAX_EDGES, Integer.parseInt(edgeAmountField.getText()));
+			params.set(params.EDIT_EDGES, chckbxEditEdges.isSelected());
+			params.set(params.POPULATION_SIZE, Integer.parseInt(popSizeField.getText()));
+			params.set(params.TOURNAMENT_SIZE, Integer.parseInt(tournamentSizeField.getText()));
+			params.set(params.EDGE_BREAK_AMOUNT, Integer.parseInt(edgeBreakCount.getText()));
+			params.set(params.SIM_ITERATIONS, Integer.parseInt(iterationsField.getText()));
+			params.set(params.EDGE_MUTATION_PROB, Double.parseDouble(edgeMutationField.getText()));
+			params.set(params.SUPPLIED_POINTS, Double.parseDouble(suppliedField.getText()));
+			params.set(params.OVERSUPPLIED_POINTS, Double.parseDouble(oversuppliedField.getText()));
+			params.set(params.UNDERSUPPLIED_POINTS, Double.parseDouble(undersuppliedField.getText()));
+			params.set(params.LENGTH_POINTS, Double.parseDouble(edgeLengthField.getText()));
+			params.set(params.WILDCARD_USAGE, Double.parseDouble(wildcardUsageField.getText()));
+			params.set(params.WILDCARD_MUTATION_PROB, Double.parseDouble(wildcardMutationField.getText()));
+			params.set(params.PARTIALSUPPLIED_POINTS, Double.parseDouble(partialSuppliedField.getText()));
+			params.set(params.OVERPRODUCTION, Double.parseDouble(overproductionField.getText()));	
+			params.set(params.NODES_IN_WILDCARDS, chckbxWildNodes.isSelected());
+			params.set(params.TOURNAMENT_PROB, 0.15);
+		}
+	}
+
+	/*
+	 * This class is Kind of the controller class. It calls the algorithm methods 
+	 * and assures the results are transported to the GenAlogWindow
+	 */
+	public class GenAlgoHandler{
+		ArrayList<GenAlgoWindow> listeners = new ArrayList<GenAlgoWindow>();
+		HolegFactory factory;
+		Control controller;
+		Model model;
+		int genCount;
+
+		GeneticAlgo holegGA;
+		TournamentSelection<HolegIndividual> tRS;
+		HolegFittnessScenario hF;
+		HolegMutation hM;
+		HolegCrossover hC;
+		ArrayList<AbstractCpsObject> objSpace;
+		CpsNode theNode = new CpsNode("Node");
+		
+		public GenAlgoHandler(Control controller, Model model){
+			this.controller = controller;
+			this.model = model;
+			genCount = 1;
+			objSpace = new ArrayList<AbstractCpsObject>();
+			for(Category cat : model.getCategories()){
+				for(AbstractCpsObject obj : cat.getObjects()){
+					if(!(obj instanceof HolonWildCard) /* && obj.useForGA */){
+						objSpace.add(obj);
+					}
+				}
+			}
+			
+			ArrayList<AbstractCpsObject> origin = model.getObjectsOnCanvas();
+			ArrayList<CpsEdge> edges = model.getEdgesOnCanvas();
+			factory = new HolegFactory(objSpace, 0, 0);
+			factory.originalObjects = origin;
+			factory.originalEdges = edges;
+			
+			hC = new HolegCrossover();
+			hF = new HolegFittnessScenario(controller);
+			hM = new HolegMutation(0.01);
+			hM.setObjectSpace(objSpace);
+			tRS = new TournamentSelection<HolegIndividual>();
+			holegGA = new GeneticAlgo(tRS, hC, hM, hF, factory, 0);
+			
+		}
+		
+		public void createGeneration(int genAmount, ParameterArray params){
+			//setting the parameters of the algo components
+			factory.maxConnections = (int)params.get(params.MAX_EDGES);
+			factory.editEdges = (boolean)params.get(params.EDIT_EDGES);
+			holegGA.popSize = (int)params.get(params.POPULATION_SIZE);
+			tRS.tournamentSize = (int)params.get(params.TOURNAMENT_SIZE);
+			tRS.selectProb = (double)params.get(params.TOURNAMENT_PROB);
+			hF.setParameters(params);
+			
+			
+			if((boolean)params.get(params.NODES_IN_WILDCARDS)){
+				if(!objSpace.contains(theNode)){
+					objSpace.add(theNode);
+				}else{
+					objSpace.remove(theNode);
+				}
+			}
+			hM.setParameters(params);
+			for(int i = 0; i < genAmount; i++){
+				hF.initialize();
+				if(genCount == 1){
+					holegGA.generateRandomPopulation();
+					HolegGeneration holegGen = new HolegGeneration(genCount);
+					holegGen.setGeneration(holegGA.getSortedPopulation());
+					addGenToPopulationListeners(holegGen);
+				}else{
+					holegGA.createNextGeneration();
+					HolegGeneration holegGen = new HolegGeneration(genCount);
+					holegGen.setGeneration(holegGA.getSortedPopulation());
+					addGenToPopulationListeners(holegGen);
+				}
+			genCount++;
+			}
+		}
+		
+		public void drawIndividualWithPos(HolegIndividual hI){
+			model.setObjectsOnCanvas(new ArrayList<AbstractCpsObject>());
+			model.setEdgesOnCanvas(new ArrayList<CpsEdge>());
+			
+			hI.configurateNetwork();
+			for(int i = 0; i < hI.getIndexes().size(); i++){
+				controller.addObjectCanvas(hI.getObjectAt(i));
+			}
+			
+			for(GAEdge e : hI.getAllEdges()){
+				controller.addEdgeOnCanvas(e);
+			}
+			controller.calculateStateForCurrentTimeStep();
+			controller.updateCanvas();
+		}
+		
+		public void addListener(GenAlgoWindow listener){
+			listeners.add(listener);
+		}
+		
+		public void addGenToPopulationListeners(HolegGeneration holegGen){
+			for(GenAlgoWindow listener : listeners){
+				listener.populationCreated(holegGen);
+			}
+		}
+		
+		public ArrayList<HolegIndividual> sortPopulation(ArrayList<HolegIndividual> individuals){
+			ArrayList<HolegIndividual> sortedList = new ArrayList<HolegIndividual>();
+			for(HolegIndividual hI : individuals){
+				for(int i = 0; i <= sortedList.size(); i++){
+					if(i == sortedList.size()){
+						sortedList.add(hI);
+						break;
+					}else if(sortedList.get(i).getFittness() < hI.getFittness()){
+						sortedList.add(i, hI);
+						break;
+					}
+				}
+			}
+			return sortedList;
+		}
+		
+		public void setOriginalNetwork(){
+			HolegIndividual originIndividual = new HolegIndividual(model.getObjectsOnCanvas(),
+						model.getEdgesOnCanvas());
+			
+
+			HolegGeneration originalGen = new HolegGeneration(HolegGeneration.ORIGINAL_GEN);
+			hF.calculateFittness(originIndividual);
+			ArrayList<HolegIndividual> population = new ArrayList<HolegIndividual>();
+			population.add(originIndividual);
+			originalGen.setGeneration(population);
+			addGenToPopulationListeners(originalGen);
+		}
+	}
+
+	public class HolegIndividual{
+		
+		public ArrayList<CpsEdge> brokenEdges = new ArrayList<CpsEdge>();
+		public ArrayList<GAEdge> additionalEdges = new ArrayList<GAEdge>();
+		public ArrayList<GAEdge> originEdges = new ArrayList<GAEdge>();
+		public ArrayList<Integer> indexes = new ArrayList<Integer>();
+		public ArrayList<Integer> originIndexes = new ArrayList<Integer>();
+		public ArrayList<Integer> wildCardIndexes = new ArrayList<Integer>();
+		public ArrayList<HolegIndividual> parents = new ArrayList<HolegIndividual>();
+		public HashMap<Integer, AbstractCpsObject> indexToObjectMap = new HashMap<Integer, AbstractCpsObject>();
+		private HashMap<AbstractCpsObject, Integer> objectToIndexMap = new HashMap<AbstractCpsObject, Integer>();
+		public boolean drawn;
+		public String id;
+		public String log;
+		public String backupLog = "Individual Log";
+		public int gen;
+		public int pos;
+		private int lastIndex;
+		public double totalEdgeLength;
+		
+		public double fittness;
+		
+		public HolegIndividual(ArrayList<AbstractCpsObject> originObjects, 
+				ArrayList<CpsEdge> originalEdges){
+
+			lastIndex = 0;
+			log = "Individual Log";
+			drawn = false;
+			
+			for(AbstractCpsObject abs : originObjects){
+
+				AbstractCpsObject newObj = abs.makeCopy();
+				newObj.setPosition(abs.getPosition());
+				newObj.setId(abs.getId());
+				addObject(newObj);
+				originIndexes.add(objectToIndexMap.get(newObj));
+				if(newObj instanceof HolonWildCard){
+					wildCardIndexes.add(objectToIndexMap.get(newObj));
+				}
+				
+			}
+			
+			if(originalEdges != null){
+				for(CpsEdge e : originalEdges){
+					addOriginalEdge(e);
+				}
+			}
+		}
+		
+		public HolegIndividual(HolegIndividual indi){
+			additionalEdges = new ArrayList<GAEdge>();
+			additionalEdges.addAll(indi.getAdditionalEdges());
+			originEdges = new ArrayList<GAEdge>();
+			originEdges.addAll(indi.originEdges);
+			indexes = new ArrayList<Integer>();
+			indexes.addAll(indi.getIndexes());
+			originIndexes = new ArrayList<Integer>();
+			originIndexes.addAll(indi.originIndexes);
+			parents = new ArrayList<HolegIndividual>();
+			
+			indexToObjectMap = new HashMap<Integer, AbstractCpsObject>();
+			objectToIndexMap = new HashMap<AbstractCpsObject, Integer>();
+			Set<Integer> keys = indi.indexToObjectMap.keySet();
+			for(Integer i : keys){
+				indexToObjectMap.put(i, indi.indexToObjectMap.get(i));
+				objectToIndexMap.put(indi.indexToObjectMap.get(i), i);
+			}
+
+			lastIndex = indi.lastIndex;
+			log = "Individual Log";
+			drawn = false;
+			
+		}
+		
+		public double getFittness(){
+			return fittness;
+		}
+		
+		public void setFittness(double fittness){
+			this.fittness = fittness;
+		}
+		
+		public ArrayList<HolegIndividual> getParents(){
+			return parents;
+		}
+		
+		public void setParents(ArrayList<HolegIndividual> parents){
+			this.parents = parents;
+			for(int i = 0; i < parents.size(); i++){
+				addLogEntry("Parent" + i + ": " + parents.get(i).getId());
+			}
+			backupLog = log;
+		}
+		
+		public void setId(int Gen, int pos){
+			if(Gen > 0){
+				id = "Generation_" + Gen + " Rank_" + pos;
+			}else{
+				id = "Generation_Original";
+			}
+		}
+		
+		public String getId(){
+			return id;
+		}
+		
+		public ArrayList<AbstractCpsObject> getObjects(){
+			ArrayList<AbstractCpsObject> objects = new ArrayList<AbstractCpsObject>();
+			for(Integer i : indexes){
+				objects.add(indexToObjectMap.get(i));
+			}
+			return objects;
+		}
+		
+		public ArrayList<AbstractCpsObject> getOriginObjects(){
+			ArrayList<AbstractCpsObject> originObjects = new ArrayList<AbstractCpsObject>();
+			for(Integer i : originIndexes){
+				originObjects.add(indexToObjectMap.get(i));
+			}
+			return originObjects;
+		}
+		
+		public AbstractCpsObject getObjectWithIndex(int index){
+			return indexToObjectMap.get(index);
+		}
+		
+		public AbstractCpsObject getObjectAt(int position){
+			return indexToObjectMap.get(indexes.get(position));
+		}
+		
+		public ArrayList<Integer> getIndexes(){
+			return indexes;
+		}
+		
+		public ArrayList<Integer> getWildcardIndexes(){
+			return wildCardIndexes;
+		}
+		
+		public ArrayList<GAEdge> getAdditionalEdges(){
+			return additionalEdges;
+		}
+		
+		public ArrayList<GAEdge> getOriginalEdges(){
+			return originEdges;
+		}
+		
+		public ArrayList<GAEdge> getAllEdges(){
+			ArrayList<GAEdge> allEdges = new ArrayList<GAEdge>();
+			allEdges.addAll(additionalEdges);
+			allEdges.addAll(originEdges);
+			return allEdges;
+		}
+		
+		public void addObject(AbstractCpsObject obj){
+			addObjectWithIdx(obj, obj.getId());
+		}
+		
+		public void addObjectWithIdx(AbstractCpsObject obj, int index){
+			if(!indexToObjectMap.containsKey(index)){
+				addIndex(index);
+				indexToObjectMap.put(index, obj);
+				objectToIndexMap.put(obj, index);
+			}else{
+				objectToIndexMap.remove(indexToObjectMap.get(index));
+				indexToObjectMap.put(index, obj);
+				objectToIndexMap.put(obj, index);
+			}
+			//indexToObjectMap.put(index, obj);
+		}
+		
+		public void removeObject(int index){
+			AbstractCpsObject toRemove = indexToObjectMap.get(index);
+			HolonWildCard fill = new HolonWildCard("WildCard");
+			fill.setId(toRemove.getId());
+			fill.setPosition(toRemove.getPosition());
+			indexToObjectMap.put(index, fill);
+		}
+		
+		public void addIndex(int index){
+			for(int i = 0; i < indexes.size(); i++){
+				if(index < indexes.get(i)){
+					indexes.add(i, index);
+					return;
+				}
+			}
+			indexes.add(index);
+			return;
+		}
+		/*
+		 * posA and posB are the indexes of the Endpoints A and B in the list of Objects
+		 */
+	
+	
+		public void addEdge(int indexA, int indexB){
+			if(!edgeExists(indexA, indexB, getAllEdges())){
+				
+				if(!indexToObjectMap.containsKey(indexA)){
+					CpsNode newObjA = new CpsNode("Node");
+					addObjectWithIdx(newObjA, indexA);
+				}
+				if(!indexToObjectMap.containsKey(indexB)){
+					CpsNode newObjB = new CpsNode("Node");
+					addObjectWithIdx(newObjB, indexB);
+				}
+				additionalEdges.add(new GAEdge(indexA, indexB, indexToObjectMap.get(indexA), indexToObjectMap.get(indexB)));
+			
+			}
+		}
+		
+		public void addOriginalEdge(CpsEdge e){
+			if(indexToObjectMap.containsKey(e.getA().getId()) && indexToObjectMap.containsKey(e.getB().getId())){
+				GAEdge realEdge = new GAEdge(e.getA().getId(), e.getB().getId(),
+						indexToObjectMap.get(e.getA().getId()), indexToObjectMap.get(e.getB().getId()));
+				
+				if(!edgeExists(realEdge.aPos, realEdge.bPos, originEdges)){
+					originEdges.add(realEdge);
+				}
+			}
+		}
+		
+		public void addOriginalEdge(GAEdge e){
+			if(!edgeExists(e.aPos, e.bPos, originEdges)){
+				originEdges.add(new GAEdge(e.aPos, e.bPos, indexToObjectMap.get(e.aPos), 
+						indexToObjectMap.get(e.bPos)));
+			}
+		}
+		
+		public boolean edgeExists(int indexA, int indexB, ArrayList<GAEdge> edges){
+			for(GAEdge e : edges){
+				if((e.aPos == indexA && e.bPos == indexB) || (e.bPos == indexA && e.aPos == indexB)){
+					return true;
+				}
+			}
+			return false;
+		}
+		
+		public void addLogEntry(String entry){
+			log += "\n" + entry;
+		}
+		
+		public void resetLog(){
+			log = backupLog;	
+		}
+		
+		public int getAvailableIndex(){
+			for(int i = 0; i <= indexes.size(); i++){
+				if(!indexes.contains(i)){
+					return i;
+				}
+			}
+			return -1;
+		}
+		
+		
+		public void configurateNetwork(){
+			//hier womöglich vorher alle edges von allen Knoten entfernen
+			for(GAEdge e : getAllEdges()){
+				e.setA(indexToObjectMap.get(e.aPos));
+				e.setB(indexToObjectMap.get(e.bPos));
+				e.revalidateConnection();
+			}
+		}
+
+		public void setEdgeLength(double doubleValue) {
+			totalEdgeLength = doubleValue;
+		}
+	}
+	
+	public class HolegGeneration{
+		public static final int ORIGINAL_GEN = -1;
+		
+		ArrayList<HolegIndividual> generation;
+		int genCount;
+		String name;
+		String log;
+		
+		public HolegGeneration(int genCount){
+			this.genCount = genCount;
+			generation = new ArrayList<HolegIndividual>();
+			if(genCount >= 0){
+				name = "Generation " + genCount;
+			}else{
+				name = "Original Network";
+			}
+		}
+		
+		
+		
+		public void setGeneration(ArrayList<HolegIndividual> generation){
+			this.generation = generation;
+		}
+		
+		public ArrayList<HolegIndividual> getGeneration(){
+			return generation;
+		}
+		
+		public int getGenCount(){
+			return genCount;
+		}
+		
+		@Override
+		public String toString(){
+			return name;
+		}
+		
+		public String getInformation(){
+			log = "Generation Log";
+			if(generation.size() > 0){
+				addLogEntry("Avg Fittness: " + getAvgFittness());
+				addLogEntry("Max Fittness: " + getMaxFittness());
+				addLogEntry("Min Fittness: " + getMinFittness());
+			}
+			return log;
+		}
+		
+		public double getAvgFittness(){
+			double fittness = 0;
+			for(HolegIndividual i : generation){
+				fittness += i.getFittness();
+			}
+			
+			return (fittness/generation.size());
+		}
+		
+		public double getMinFittness(){
+			double fittness = generation.get(0).getFittness();
+			for(HolegIndividual i : generation){
+				if(i.getFittness() < fittness){
+					fittness = i.getFittness();
+				}
+			}
+			return fittness;
+		}
+		
+		public double getMaxFittness(){
+			double fittness = generation.get(0).getFittness();
+			for(HolegIndividual i : generation){
+				if(i.getFittness() > fittness){
+					fittness = i.getFittness();
+				}
+			}
+			return fittness;
+		}
+		
+		public void addLogEntry(String entry){
+			log += "\n" + entry;
+		}
+	}
+	
+	public class ParameterArray{
+		public static final int POPULATION_SIZE = 0;
+		public static final int TOURNAMENT_SIZE = 1;
+		public static final int EDIT_EDGES = 2;
+		public static final int MAX_EDGES = 3;
+		public static final int EDGE_BREAK_AMOUNT = 4;
+		public static final int SIM_ITERATIONS = 5;
+		public static final int EDGE_MUTATION_PROB = 6;
+		public static final int SUPPLIED_POINTS = 7;
+		public static final int UNDERSUPPLIED_POINTS = 8;
+		public static final int OVERSUPPLIED_POINTS = 9;
+		public static final int LENGTH_POINTS = 10;
+		public static final int WILDCARD_MUTATION_PROB = 11;
+		public static final int PARTIALSUPPLIED_POINTS = 12;
+		public static final int WILDCARD_USAGE = 13;
+		public static final int OVERPRODUCTION = 14;
+		public static final int NODES_IN_WILDCARDS = 15;
+		public static final int OBJECT_SPACE = 16;
+		public static final int ORIGINAL_NETWORK = 17;
+		public static final int TOURNAMENT_PROB = 18;
+		
+		public ArrayList<Object> list = new ArrayList<Object>();
+		
+		public ParameterArray(){
+			for(int i = 0; i < 19; i++){
+				list.add(new Object());
+			}
+		}
+		
+		public Object get(int index){
+			return list.get(index);
+		}
+		
+		public <T extends Object> void set(int index, T object){
+			list.set(index, object);
+		}
+	}
+	
+	public class GAEdge extends CpsEdge{
+		public int aPos;
+		public int bPos;
+		
+		public GAEdge(int a, int b, AbstractCpsObject nodeA, AbstractCpsObject nodeB){
+			//super(nodeA,nodeB, CAPACITY_INFINITE);
+			super(nodeA,nodeB, 100000);
+			aPos = a;
+			bPos = b;
+		}
+		
+		public void revalidateConnection(){
+			if(!this.getA().getConnections().contains(this)){
+				this.getA().getConnections().add(this);
+			}
+			if(!this.getB().getConnections().contains(this)){
+				this.getB().getConnections().add(this);
+			}
+		}
+	}
+	
+	public class HolonWildCard extends AbstractCpsObject{
+		AbstractCpsObject holdingObject;
+		
+		public HolonWildCard(String objName){
+			super(objName);
+			this.setConnections(new ArrayList<CpsEdge>());
+			this.setImage("/Images/wildCard.png");
+			this.setSav("CVS");
+			this.setId(IdCounter.nextId());
+			holdingObject = this;
+		}
+
+		public HolonWildCard(AbstractCpsObject obj) {
+			super(obj);
+			holdingObject = this;
+			
+		}
+
+		//@Override
+		public AbstractCpsObject makeCopy() {
+			return new HolonWildCard(this);
+		}
+		
+		public void setHoldingObject(AbstractCpsObject object){
+			this.holdingObject = object;
+		}
+		
+		public AbstractCpsObject getHoldingObject(){
+			return holdingObject;
+		}
+	}
+
+	public class GeneticAlgo{
+		public int popSize;
+		public ArrayList<HolegIndividual> population;
+		
+		public HolegFactory randomFactory;
+		public TournamentSelection<HolegIndividual> selector;
+		public HolegCrossover reproducer;
+		public HolegMutation mutator;
+		public HolegFittnessScenario fittnessFunction;
+		public double topPercent;
+		public double buttomPercent;
+		
+		public GeneticAlgo(TournamentSelection<HolegIndividual> selection, HolegCrossover crossover, 
+				HolegMutation mutator, HolegFittnessScenario fittnessFkt, 
+				HolegFactory factory, int popSize){
+			
+			this.selector = selection;
+			this.reproducer = crossover;
+			this.mutator = mutator;
+			this.fittnessFunction = fittnessFkt;
+			randomFactory = factory;
+			this.popSize = popSize;
+			
+			population = new ArrayList<HolegIndividual>();
+			topPercent = 0.05;
+			
+			//generateRandomPopulation();
+		}
+
+		public void generateRandomPopulation() {
+			population = new ArrayList<HolegIndividual>();
+			for(int i = 0; i < popSize; i++){
+				population.add(randomFactory.createRandomIndividual());
+				fittnessFunction.calculateFittness(population.get(i));
+			}
+		}
+		
+		public void createNextGeneration(){
+			ArrayList<HolegIndividual> nextGen = new ArrayList<HolegIndividual>();
+			
+			
+			int topBound = (int) Math.ceil(topPercent * popSize);
+			//int topBound = 1;
+			population = getSortedPopulation();
+			
+			for(HolegIndividual individual : population.subList(0, topBound)){
+				ArrayList<HolegIndividual> childs = new ArrayList<HolegIndividual>();
+				childs.add(individual);
+				childs.add(individual);
+				childs = reproducer.crossOver(childs);
+				for(HolegIndividual i : childs){
+					i.addLogEntry("Top % from previous gen");
+					fittnessFunction.calculateFittness(i);
+					nextGen.add(i);
+				}
+			}
+			
+			selector.setCurrentPopulation(population);
+			while(nextGen.size() < popSize){
+				ArrayList<HolegIndividual> freshInds = new ArrayList<HolegIndividual>();
+				freshInds = reproducer.crossOver(selector.selectIndividuals());
+				for(HolegIndividual i : freshInds){
+					i = mutator.mutateIndividual(i);
+					fittnessFunction.calculateFittness(i);
+				}
+				nextGen.addAll(freshInds);
+			}
+			
+			if(popSize % 2 == 1){
+				Random rnd = new Random();
+				nextGen.remove(rnd.nextInt(popSize));
+			}
+			population = nextGen;
+		}
+		
+		public ArrayList<HolegIndividual> getPopulation(){
+			return population;
+		}
+		
+		public ArrayList<HolegIndividual> getSortedPopulation(){
+			return sortPopulation(population);
+		}
+		
+		public ArrayList<HolegIndividual> sortPopulation(ArrayList<HolegIndividual> individuals){
+			ArrayList<HolegIndividual> sortedList = new ArrayList<HolegIndividual>();
+			for(HolegIndividual hI : individuals){
+				for(int i = 0; i <= sortedList.size(); i++){
+					if(i == sortedList.size()){
+						sortedList.add(hI);
+						break;
+					}else if(sortedList.get(i).getFittness() < hI.getFittness()){
+						sortedList.add(i, hI);
+						break;
+					}
+				}
+			}
+			return sortedList;
+		}
+	}
+
+	public class HolegFactory{
+		ArrayList<AbstractCpsObject> objectSpace;
+		public ArrayList<AbstractCpsObject> originalObjects;
+		public ArrayList<CpsEdge> originalEdges;
+		public int maxObjects;
+		public int maxConnections;
+		HolegMutation mutation;
+		Random rng;
+		public boolean editEdges;
+		
+		public HolegFactory(ArrayList<AbstractCpsObject> objects, int maxObjects, int maxConnections){
+			objectSpace = objects;
+			this.maxObjects = maxObjects;
+			this.maxConnections = maxConnections;
+			rng = new Random();
+			originalObjects = new ArrayList<AbstractCpsObject>();
+			originalEdges = new ArrayList<CpsEdge>();
+			editEdges = false;
+			mutation = new HolegMutation();
+		}
+		
+		public HolegIndividual createRandomIndividual() {
+			HolegIndividual hI = new HolegIndividual(originalObjects, originalEdges);
+			setWildCards(hI);
+			if(editEdges){
+				editEdges(hI);
+			}
+			if(maxConnections > 0){
+				createEdges(hI);
+			}
+			return hI;
+		}
+
+		private void setWildCards(HolegIndividual hI) {
+			int setAmount = rng.nextInt(hI.getWildcardIndexes().size() + 1);
+			ArrayList<Integer> list = new ArrayList<Integer>();
+			list.addAll(hI.getWildcardIndexes());
+			Collections.shuffle(list);
+			int spaceIdx = 0;
+			if(objectSpace.size() > 0){
+				for(int i = 0; i < setAmount; i++){
+					AbstractCpsObject wildCard = hI.indexToObjectMap.get(list.get(i));
+					spaceIdx = rng.nextInt(objectSpace.size());
+					AbstractCpsObject newObj = objectSpace.get(spaceIdx).makeCopy();
+					newObj.setPosition(wildCard.getPosition());
+					newObj.setId(wildCard.getId());
+					hI.addObjectWithIdx(newObj, newObj.getId());
+				}
+			}
+		}
+		
+		private void editEdges(HolegIndividual hI) {
+			if(hI.getOriginalEdges().size() > 0 && hI.getIndexes().size() > 2){
+				int editAmount = rng.nextInt(hI.getOriginalEdges().size());
+				for(int i = 0; i < editAmount; i++){
+					int edgeIdx = rng.nextInt(hI.getOriginalEdges().size());
+					GAEdge toChange = hI.getOriginalEdges().get(edgeIdx);
+					mutation.changeSingleEdge(hI, toChange, true);
+				}
+			}
+		}
+
+		public void createObjects(HolegIndividual hI){
+		
+			int objCount = rng.nextInt(maxObjects) + 1;
+			
+			for(int i = 0; i < objCount; i++){
+				
+				
+				AbstractCpsObject newObj = null;
+				if(!editEdges){
+					AbstractCpsObject absObj = objectSpace.get(rng.nextInt(objectSpace.size()));
+					if(absObj instanceof HolonObject){
+						newObj = new HolonObject(absObj);
+					}else if(absObj instanceof HolonSwitch){
+						newObj = new HolonSwitch(absObj);
+					}else if(absObj instanceof HolonBattery){
+						newObj = new HolonBattery(absObj);
+					}else if(absObj instanceof HolonWildCard){
+						newObj = new HolonWildCard(absObj);
+					}else if(absObj == null){
+						newObj = new CpsNode("Node");
+					}
+				}else{
+					newObj = new CpsNode("Node");
+				}
+				
+				hI.addObject(newObj);
+			}
+		}
+		
+		public void createEdges(HolegIndividual hI){
+			if(hI.getIndexes().size() > 1){
+				int edgeCount = rng.nextInt(maxConnections + 1);
+				ArrayList<Integer> list = new ArrayList<Integer>();
+		    
+				for (int i = 0; i < hI.getIndexes().size(); i++) {
+					list.add(hI.getIndexes().get(i));
+				}
+		   
+				if(edgeCount >= hI.getAllEdges().size()){
+					edgeCount -= hI.getAllEdges().size();
+				}else{
+					edgeCount = 0;
+				}
+				for(int i = 0; i < edgeCount; i++){
+					Collections.shuffle(list);
+					int aPos = list.get(0);
+					int bPos = list.get(1);
+					hI.addEdge(aPos, bPos);
+				}
+			}
+
+		}
+	}
+	
+	public class TournamentSelection<I extends HolegIndividual>{
+		public class Range{
+			
+			public double min;
+			public double max;
+			public Range(double min, double max){
+				this.min = min;
+				this.max = max;
+			}
+		}
+		
+		private ArrayList<I> currentPop;
+		public int tournamentSize;
+		private Random rng; 
+		private ArrayList<Range> tournamentWheel;
+		public ArrayList<I> competitors;
+		public double selectProb;
+		private double maxRange;
+		
+		
+		public TournamentSelection(){
+			currentPop = new ArrayList<I>();
+			tournamentSize = 1;
+			rng = new Random();
+			selectProb = 1;
+		}
+		
+		public TournamentSelection(int tSize, double selectProb){
+			currentPop = new ArrayList<I>();
+			rng = new Random();
+			tournamentSize = tSize;
+			this.selectProb = selectProb;
+		}
+		
+		public void setCurrentPopulation(ArrayList<I> population) {
+			currentPop = population;
+		}
+		
+		public void setTournamentSize(int size){
+			tournamentSize = size;
+		}
+
+		public ArrayList<I> selectIndividuals() {
+			ArrayList<I> parents = new ArrayList<I>();
+			parents.add(selectSingleIndividual());
+			parents.add(selectSingleIndividual());
+			return parents;
+		}
+		
+		public I selectSingleIndividual(){
+			tournamentSelection();
+			initWheel();
+			double index = rng.nextDouble() * maxRange;
+			for(int i = 0; i < tournamentWheel.size(); i++){
+				if(index >= tournamentWheel.get(i).min && index <= tournamentWheel.get(i).max){
+					return competitors.get(i);
+				}
+			}
+			return competitors.get(rng.nextInt(competitors.size()));
+		}
+		
+		public void tournamentSelection(){
+			competitors = new ArrayList<I>();
+			for(int i = 0; i < tournamentSize; i++){
+				I candidate = chooseCandidate();
+				int size = competitors.size();
+				for(int j = 0; j <= size; j++){
+					if(j != size){
+						if(competitors.get(j).getFittness() < candidate.getFittness()){
+							competitors.add(j, candidate);
+							break;
+						}
+					}else{
+						competitors.add(candidate);
+					}
+				}
+			}		
+		}
+		
+		public I chooseCandidate(){
+			int index = rng.nextInt(currentPop.size());
+			I candidate = currentPop.get(index);
+			return candidate;
+		}
+		
+		public void initWheel(){
+			tournamentWheel = new ArrayList<Range>();
+			int power = 0;
+			maxRange = 0;
+			for(int i = 0; i < tournamentSize; i++){
+				double currentProb = selectProb * Math.pow((1- selectProb), power);
+				Range range = new Range(maxRange, maxRange + currentProb);
+				tournamentWheel.add(range);
+				maxRange += currentProb;
+				power++;
+			}
+		}
+	}
+	
+	public class HolegFittnessScenario{
+		HolegFittnessFkt singleFkt;
+		Control controller;
+		Model model;
+		SimulationManager simManager;
+		ParameterArray params;
+		int edgeBreakCount;
+		double edgeLengthPoints;
+		double wildcardPoints;
+		double overprodPoints;
+		int totalSteps = 100;
+		int singleStep;
+		int breakCounter = 0;
+		HolegIndividual originalNetwork;
+		ArrayList<Integer> edgeBreakingIndexes = new ArrayList<Integer>();
+		double globalOverProd;
+		Random rng = new Random();
+			
+		public HolegFittnessScenario(Control controller) {
+			singleFkt = new HolegFittnessFkt(controller);
+			model = singleFkt.getModel();
+			
+		}
+		
+		public double calculateFittness(HolegIndividual candidate) {
+			globalOverProd = 0;
+			double fittness = 0;
+			double noBreakFittness = calcFittnessWithoutBreak(candidate);
+			fittness += noBreakFittness;
+			candidate.addLogEntry("Fittness without break: " + noBreakFittness);
+			double breakFittness = calcFittnessWithBreak(candidate);
+			candidate.addLogEntry("Fittness with break: " + breakFittness);
+			fittness += breakFittness;
+			fittness = fittness /2;
+			globalOverProd = globalOverProd / 2;
+			globalOverProd = globalOverProd / totalSteps;
+			
+			for(Integer wildIdx : candidate.getWildcardIndexes()){
+				if(!(candidate.indexToObjectMap.get(wildIdx) instanceof HolonWildCard)){
+					fittness += wildcardPoints;
+				}
+			}
+			
+			double edgeLength = 0;
+			for(GAEdge e : candidate.getAllEdges()){
+				Position aPos = e.getA().getPosition();
+				Position bPos = e.getB().getPosition();
+				double xDiff = Math.abs(aPos.x - bPos.x);
+				double yDiff = Math.abs(aPos.y - bPos.y);
+				edgeLength += Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));
+			}
+			
+			candidate.setEdgeLength(getRoundedValue(edgeLength));
+			candidate.addLogEntry("Total Edge Length: " + getRoundedValue(edgeLength));
+			fittness += (edgeLength/100)*edgeLengthPoints;
+			
+			candidate.addLogEntry("average Overproduction: " + getRoundedValue(globalOverProd));
+			
+			candidate.setFittness(getRoundedValue(fittness));		
+			candidate.addLogEntry("Fittness: " + getRoundedValue(fittness));
+			return fittness;
+		}
+		
+		public double calcFittnessWithoutBreak(HolegIndividual candidate){
+			double fittness = 0;
+			double avgOverProduction = 0;
+			
+			for(CpsEdge edge : candidate.brokenEdges){
+				//edge.setWorkingState(true);
+			}
+			candidate.brokenEdges.clear();
+			
+			for(int i = 0; i < totalSteps; i++){
+				model.setCurIteration(singleStep * i);
+				fittness += singleFkt.calculateFittness(candidate);
+				avgOverProduction += singleFkt.getCurrentOverProduction();
+			}
+			
+			globalOverProd += avgOverProduction;
+			fittness += (avgOverProduction / 1000) * overprodPoints;
+			fittness = (int)fittness;
+			fittness = fittness/totalSteps;
+			return fittness;
+		}
+		
+		public double calcFittnessWithBreak(HolegIndividual candidate){
+			double fittness = 0;
+			double avgOverProduction = 0;
+			
+			for(CpsEdge edge : candidate.brokenEdges){
+				//edge.setWorkingState(true);
+			}
+
+			breakEdges(candidate);
+			
+			for(int i = 0; i < totalSteps; i++){
+				model.setCurIteration(singleStep * i);
+				fittness += singleFkt.calculateFittness(candidate);
+				avgOverProduction += singleFkt.getCurrentOverProduction();
+			}
+			
+			globalOverProd += avgOverProduction;
+			fittness += (avgOverProduction / 1000) * overprodPoints;
+			fittness = (int)fittness;
+			fittness = fittness/totalSteps;
+
+			return fittness;
+		}
+		
+		private void breakEdges(HolegIndividual candidate) {
+			candidate.brokenEdges.clear();
+			int unbrokenEdges = 0;
+			for(Integer idx : edgeBreakingIndexes){
+				ArrayList<CpsEdge> healthyEdges = new ArrayList<CpsEdge>();
+				
+				
+				for(CpsEdge edge : candidate.indexToObjectMap.get(idx).getConnections()){
+					/*
+					if(edge.isWorking()){
+						healthyEdges.add(edge);
+					}
+					*/
+				}
+			
+				Collections.shuffle(healthyEdges);
+				if(healthyEdges.size() > 0){
+					//healthyEdges.get(0).setWorkingState(false);
+					candidate.brokenEdges.add(healthyEdges.get(0));
+				}else{
+					unbrokenEdges++;
+				}
+			}
+			if(unbrokenEdges > 0){
+				ArrayList<CpsEdge> healthyEdges = new ArrayList<CpsEdge>();
+				for(CpsEdge edge : candidate.getAllEdges()){
+					/*
+					if(edge.isWorking()){
+						healthyEdges.add(edge);
+					}
+					*/
+				}
+				Collections.shuffle(healthyEdges);
+				int bound;
+				if(unbrokenEdges <= healthyEdges.size()){
+					bound = unbrokenEdges;
+				}else{
+					bound = healthyEdges.size();
+				}
+				for(int i = 0; i < bound; i++){
+					//healthyEdges.get(i).setWorkingState(false);
+				}
+			}
+			
+		}
+
+		public void setParameters(ParameterArray params){
+			this.params = params;
+			edgeBreakCount = (int)params.get(params.EDGE_BREAK_AMOUNT);
+			edgeLengthPoints = (double)params.get(params.LENGTH_POINTS);
+			wildcardPoints = (double)params.get(params.WILDCARD_USAGE);
+			totalSteps = (int)params.get(params.SIM_ITERATIONS);
+			overprodPoints = (double)params.get(params.OVERPRODUCTION);
+			originalNetwork = (HolegIndividual)params.get(params.ORIGINAL_NETWORK);
+			if(totalSteps < 100){
+				singleStep = (int) Math.floor(100/totalSteps);
+			}else{
+				singleStep = 1;
+			}
+			
+			singleFkt.setParameters(params);
+		}
+		
+		/*
+		 * method is called before a new generation is calculated
+		 * setting the specific edge breaks here
+		 */
+		public void initialize(){
+			edgeBreakingIndexes.clear();
+			ArrayList<Integer> objIndexes = new ArrayList<Integer>();
+			objIndexes.addAll(originalNetwork.getIndexes());
+			Collections.shuffle(objIndexes);
+			//shuffeling leads to random selection of Indexes
+			int bound;
+			if(edgeBreakCount <= objIndexes.size()){
+				bound = edgeBreakCount;
+			}else{
+				bound = objIndexes.size();
+			}
+			for(int i = 0; i < bound; i++){
+				edgeBreakingIndexes.add(objIndexes.get(rng.nextInt(objIndexes.size())));
+			}
+		}
+
+		public double getRoundedValue(double value){
+			BigDecimal bd = new BigDecimal(value);
+			bd = bd.setScale(2, RoundingMode.HALF_UP);
+			return bd.doubleValue();
+		}
+	}
+	
+	public class HolegFittnessFkt{
+		Control controller;
+		Model model;
+		SimulationManager simManager;
+		ParameterArray params;
+		double suppliedPoints;
+		double oversuppliedPoints;
+		double undersuppliedPoints;
+		double partiallysuppliedPoints;
+		boolean everyoneSupplied;
+		
+		public HolegFittnessFkt(Control controller){
+			model = new Model();
+			simManager = new SimulationManager(model);
+		}
+
+		public double calculateFittness(HolegIndividual candidate){
+			model.getObjectsOnCanvas().clear();
+			model.getEdgesOnCanvas().clear();
+			candidate.configurateNetwork();
+			model.getObjectsOnCanvas().addAll(candidate.getObjects());
+			model.getEdgesOnCanvas().addAll(candidate.getAllEdges());
+			simManager.calculateStateForTimeStep(model.getCurIteration());
+			
+			DecoratedState state = simManager.getDecorState(model.getCurIteration());
+			
+			everyoneSupplied = true;
+			double fittness = 0;
+			for(DecoratedNetwork net : state.getNetworkList()){
+				fittness += net.getConsumerSelfSuppliedList().stream().map(con -> con.getState()).map(objState -> StateToFitness(objState)).reduce(0.0,(a,b)->(a+b));
+				fittness += net.getConsumerList().stream().map(con -> con.getState()).map(objState -> StateToFitness(objState)).reduce(0.0,(a,b)->(a+b));
+			}
+			return fittness;
+		}
+		
+		public double StateToFitness(HolonObjectState state){
+			switch (state) {
+			case NOT_SUPPLIED:
+				return undersuppliedPoints;
+			case NO_ENERGY:
+				return 0f;
+			case OVER_SUPPLIED:
+				return oversuppliedPoints;
+			case PARTIALLY_SUPPLIED:
+				return partiallysuppliedPoints;
+			case PRODUCER:
+				return 0f;
+			case SUPPLIED:
+				return suppliedPoints;
+			default:
+				return 0f;
+			}
+		}
+		
+		public float getCurrentOverProduction(){
+			float overProd = 0;
+			/*
+			for(SubNet subnet : simManager.getSubNets()){
+				overProd += subnet.spareProduction;
+			}
+			 * */
+			return overProd;
+		}
+		
+		public boolean getEveryoneSupplied(){
+			return everyoneSupplied;
+		}
+		
+		public Model getModel(){
+			return model;
+		}
+		
+		public void setParameters(ParameterArray params){
+			this.params = params;
+			suppliedPoints = (double)params.get(params.SUPPLIED_POINTS);
+			oversuppliedPoints = (double)params.get(params.OVERSUPPLIED_POINTS);
+			undersuppliedPoints = (double)params.get(params.UNDERSUPPLIED_POINTS);
+			partiallysuppliedPoints = (double)params.get(params.PARTIALSUPPLIED_POINTS);
+		}
+	}
+
+	public class HolegCrossover{
+		protected double crossProb;
+		protected Random rng;
+		
+		public HolegCrossover(double prob){
+			crossProb = prob;
+			rng = new Random();
+		}
+		
+		public HolegCrossover(){
+			crossProb = 0.7;
+			rng = new Random();
+		}
+		
+		public void setCrossoverProbability(double prob){
+			crossProb = prob;
+		}
+		
+		public double getCrossoverProbability(){
+			return crossProb;
+		}
+		
+		public ArrayList<HolegIndividual> crossOver(ArrayList<HolegIndividual> parents) {
+			HolegIndividual parent1 = parents.get(0);
+			HolegIndividual parent2 = parents.get(1);
+			ArrayList<HolegIndividual> children = new ArrayList<HolegIndividual>();
+			children.add(createChild(parent1, parent2));
+			children.add(createChild(parent2, parent1));
+			return children;
+		}
+
+		private HolegIndividual createChild(HolegIndividual parent1, HolegIndividual parent2) {
+			HolegIndividual child = new HolegIndividual(parent1.getOriginObjects(), null);
+			ArrayList<HolegIndividual> parents = new ArrayList<HolegIndividual>();
+			parents.add(parent1);
+			parents.add(parent2);
+			child.setParents(parents);
+			
+			ArrayList<Integer> parent1WildCardIndexes = parent1.wildCardIndexes;
+			int splitIdx = (int) Math.ceil((double)parent1WildCardIndexes.size()/2);
+			
+			for(int i = 0; i < splitIdx; i++){
+				int index = parent1WildCardIndexes.get(i);
+				
+				AbstractCpsObject wildObj = parent1.indexToObjectMap.get(index);
+				AbstractCpsObject newWildObj = wildObj.makeCopy();
+				newWildObj.setId(wildObj.getId());
+				newWildObj.setPosition(wildObj.getPosition());
+				child.addObject(newWildObj);
+			}
+			int restAmount = parent1WildCardIndexes.size() - splitIdx;
+			
+			ArrayList<Integer> parent2WildCardIndexes = parent2.wildCardIndexes;
+			for(int j = 0; j < restAmount; j++){
+				int index = parent2WildCardIndexes.size() - 1; //greift auf letztes element zu
+				index -= j;	//greift bei jedem durchlauf auf ein weiter vorderes element zu
+				if(index >= 0){
+					int objIdx = parent2WildCardIndexes.get(index);
+					
+					AbstractCpsObject wildObj = parent2.indexToObjectMap.get(objIdx);
+					AbstractCpsObject newWildObj = wildObj.makeCopy();
+					newWildObj.setId(wildObj.getId());
+					newWildObj.setPosition(wildObj.getPosition());
+					child.addObject(newWildObj);
+				}else{
+					break;
+				}
+			}
+			
+			child.wildCardIndexes = parent1.wildCardIndexes;
+			
+			//OriginEdges
+			splitIdx = (int) Math.ceil((double)parent1.getOriginalEdges().size()/2);
+			for(int i = 0; i < splitIdx; i++){
+				child.addOriginalEdge(parent1.getOriginalEdges().get(i));
+			}
+			
+			restAmount = parent1.getOriginalEdges().size() - splitIdx;
+			for(int j = 0; j < restAmount; j++){
+				int idx = parent2.getOriginalEdges().size() - 1;
+				idx -= j;
+				if(idx >= 0){
+					child.addOriginalEdge(parent2.getOriginalEdges().get(idx));
+				}
+			}
+			
+			//HolonEdges
+			splitIdx = (int) Math.ceil((double)parent1.getAdditionalEdges().size()/2);
+			for(int k = 0; k < splitIdx; k++){
+				int posA = parent1.getAdditionalEdges().get(k).aPos;
+				int posB = parent1.getAdditionalEdges().get(k).bPos;
+				
+				child.addEdge(posA, posB);
+			}
+			
+			restAmount = parent1.getAdditionalEdges().size() - splitIdx;
+			for(int l = 0; l < restAmount; l++){
+				int idx = parent2.getAdditionalEdges().size() - 1;
+				idx -= l;
+				
+				if(idx >= 0){
+					int posA = parent2.getAdditionalEdges().get(idx).aPos;
+					int posB = parent2.getAdditionalEdges().get(idx).bPos;
+					
+					child.addEdge(posA, posB);
+				}
+			}
+			return child;
+		}
+	}
+
+	public class HolegMutation{
+		protected double mutationProb;
+		public Random rng = new Random();
+		
+		public final int ADD_EDGE = 0;
+		public final int REMOVE_EDGE = 1;
+		public final int CHANGE_OBJECT = 0;
+		public final int REMOVE_OBJECT = 1;
+		ArrayList<AbstractCpsObject> objSpace;
+		public boolean editEdges = false;
+		public int maxConnections = 0;
+		public double edgeMutationProb = 0;
+		
+		public HolegMutation(){
+			mutationProb = 0.001;
+			rng = new Random();
+		}
+		
+		public HolegMutation(double prob){
+			mutationProb = prob;
+		}
+		
+		public void setMutationProbability(double probability){
+			mutationProb = probability;
+		}
+		
+		public double getMutationProbability(){
+			return mutationProb;
+		}
+
+		public HolegIndividual mutateIndividual(HolegIndividual mutant) {
+			
+			for(Integer wildIdx : mutant.getWildcardIndexes()){
+				if(rng.nextDouble() < mutationProb){
+					switch(rng.nextInt(2)){
+					case CHANGE_OBJECT :
+						changeObject(mutant, wildIdx);
+						break;
+					case REMOVE_OBJECT :
+						removeObject(mutant, wildIdx);
+						break;
+					}
+				}
+			}
+			
+			ArrayList<GAEdge> mutationEdges = new ArrayList<GAEdge>();
+			
+			int endIdx = 0;
+			boolean isOriginal = false;
+
+			if(editEdges){
+				mutationEdges.addAll(mutant.getOriginalEdges());
+				endIdx = mutationEdges.size(); //originalEdges müssen zuerst mutieren da sie sonst 
+												//verworfen werden falls additional Edge gleiche werte bekommt
+				mutationEdges.addAll(mutant.getAdditionalEdges());
+			}else{
+				mutationEdges.addAll(mutant.getAdditionalEdges());
+			}
+			
+			for(int i = 0; i < mutationEdges.size(); i++){
+				if(rng.nextDouble() < edgeMutationProb){
+					if(i < endIdx){
+						changeSingleEdge(mutant, mutationEdges.get(i), true);
+					}else{
+						changeSingleEdge(mutant, mutationEdges.get(i), false);
+					}
+				}
+			}
+			
+			if(rng.nextDouble() < edgeMutationProb){
+				switch(rng.nextInt(2)){
+				case ADD_EDGE:
+					addEdge(mutant);
+					break;
+				case REMOVE_EDGE:
+					removeEdge(mutant);
+					break;
+				}
+				
+			}
+			return mutant;
+		}
+
+		public void removeObject(HolegIndividual mutant, int removeIdx) {
+				ArrayList<CpsEdge> connections = new ArrayList<CpsEdge>();
+				connections.addAll(mutant.getObjectWithIndex(removeIdx).getConnections());
+				for(CpsEdge e : connections){
+					e.getA().getConnections().remove(e);
+					e.getB().getConnections().remove(e);
+				}
+				ArrayList<GAEdge> edgesToRemove = new ArrayList<GAEdge>();
+				for(GAEdge  gE : mutant.getAllEdges()){
+					if(gE.aPos == removeIdx || gE.bPos == removeIdx){
+						edgesToRemove.add(gE);
+					}
+				}
+				mutant.getAllEdges().removeAll(edgesToRemove);
+				mutant.addLogEntry("Object wit ID " + mutant.indexToObjectMap.get(removeIdx).getId() + " removed");
+				mutant.removeObject(removeIdx);
+		}
+
+		public void changeObject(HolegIndividual mutant, int changeIdx) {
+			if(objSpace.size() > 0){
+				AbstractCpsObject newObj = null;
+				AbstractCpsObject absObj = objSpace.get(rng.nextInt(objSpace.size()));
+				newObj = absObj.makeCopy();
+			
+				AbstractCpsObject oldObject = mutant.getObjectWithIndex(changeIdx);
+				for(CpsEdge e : oldObject.getConnections()){
+					if(e.getA() == oldObject){
+						e.setA(newObj);
+						newObj.addConnection(e);
+					}else if(e.getB() == oldObject){
+						e.setB(newObj);
+						newObj.addConnection(e);
+					}
+				}
+				newObj.setId(oldObject.getId());
+				newObj.setPosition(oldObject.getPosition());
+			
+				mutant.indexToObjectMap.put(changeIdx, newObj);
+				mutant.addLogEntry("Object with Id " + newObj.getId() + " changed");
+			}
+		}
+
+		public void removeEdge(HolegIndividual mutant) {
+			ArrayList<GAEdge> edgesSpace = new ArrayList<GAEdge>();
+			int spaceEndIdx = 0;
+			if(editEdges){
+				
+				edgesSpace.addAll(mutant.getAdditionalEdges());
+				spaceEndIdx = edgesSpace.size();
+				edgesSpace.addAll(mutant.getOriginalEdges());
+				
+			}else{
+				edgesSpace.addAll(mutant.getAdditionalEdges());
+				spaceEndIdx = edgesSpace.size();
+			}
+			if(edgesSpace.size() > 0){
+				int edgeIdx = rng.nextInt(edgesSpace.size());
+				CpsEdge toRemove = edgesSpace.get(edgeIdx);
+				toRemove.getA().getConnections().remove(toRemove);
+				toRemove.getB().getConnections().remove(toRemove);
+				if(edgeIdx < spaceEndIdx){
+					mutant.getAdditionalEdges().remove(edgeIdx);
+				}else{
+					mutant.getOriginalEdges().remove(edgeIdx-spaceEndIdx);
+				}
+				mutant.addLogEntry("Edge (" + toRemove.getA().getId() + ","
+					+ toRemove.getB().getId() + ") removed");
+			}
+		}
+
+		public void addEdge(HolegIndividual mutant) {
+			if(mutant.getAllEdges().size() < maxConnections){
+				if(mutant.getIndexes().size() > 1){
+					ArrayList<Integer> list = new ArrayList<Integer>();
+					list.addAll(mutant.getIndexes());
+					Collections.shuffle(list);
+					int aPos = list.get(0);
+					int bPos = list.get(1);
+					mutant.addEdge(aPos, bPos);
+					mutant.addLogEntry("Edge (" + mutant.indexToObjectMap.get(aPos).getId() + 
+						"," + mutant.indexToObjectMap.get(bPos).getId() + ") added");
+				}
+			}
+		}
+
+		public void changeRandomEdge(HolegIndividual mutant) {
+			ArrayList<GAEdge> edgeSpace;
+			if(editEdges){
+				edgeSpace = mutant.getAllEdges();
+			}else{
+				edgeSpace = mutant.getAdditionalEdges();
+			}
+			
+			if(edgeSpace.size() > 0){
+				int edgeIdx = rng.nextInt(edgeSpace.size());
+				GAEdge toChange = edgeSpace.get(edgeIdx);
+				boolean changeA = rng.nextBoolean();
+				int randomIndex = rng.nextInt(mutant.getIndexes().size());
+				randomIndex = mutant.getIndexes().get(randomIndex);
+				if(changeA){
+					toChange.getA().getConnections().remove(toChange);
+					if(toChange.getB() != mutant.getObjectWithIndex(randomIndex)){
+						toChange.setA(mutant.getObjectWithIndex(randomIndex));
+						toChange.aPos = randomIndex;
+						mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
+					}else{
+						toChange.getB().getConnections().remove(toChange);
+						mutant.getAdditionalEdges().remove(toChange);
+					}
+				}else{
+					toChange.getB().getConnections().remove(toChange);
+					if(toChange.getA() != mutant.getObjectWithIndex(randomIndex)){
+						toChange.setB(mutant.getObjectWithIndex(randomIndex));
+						toChange.bPos = randomIndex;
+						mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
+					}else{
+						toChange.getA().getConnections().remove(toChange);
+						mutant.getAdditionalEdges().remove(toChange);
+					}
+				}
+			}
+			
+		}
+		
+		public void changeSingleEdge(HolegIndividual mutant, GAEdge toChange, boolean isOriginal){
+			boolean changeA = rng.nextBoolean();
+			int randomIndex = rng.nextInt(mutant.getIndexes().size());
+			randomIndex = mutant.getIndexes().get(randomIndex);
+			String logString = "Edge (" + toChange.aPos + "," + toChange.bPos + 
+					") changed to ";
+			if(mutant.getObjectWithIndex(randomIndex) != toChange.getA() &&
+					mutant.getObjectWithIndex(randomIndex) != toChange.getB()){
+				if(changeA && !mutant.edgeExists(randomIndex, toChange.bPos, mutant.getAllEdges())){
+					toChange.getA().getConnections().remove(toChange);
+					toChange.setA(mutant.getObjectWithIndex(randomIndex));
+					toChange.aPos = randomIndex;
+					mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
+				}else if(!mutant.edgeExists(randomIndex, toChange.aPos, mutant.getAllEdges())){
+					toChange.getB().getConnections().remove(toChange);
+					toChange.setB(mutant.getObjectWithIndex(randomIndex));
+					toChange.bPos = randomIndex;
+					mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
+					}
+			}
+			mutant.addLogEntry(logString + "(" + toChange.aPos + "," + toChange.bPos + ")");
+		}
+		
+		public void setParameters(ParameterArray params){
+			this.edgeMutationProb = (double)params.get(params.EDGE_MUTATION_PROB);
+			this.setMutationProbability((double)params.get(params.WILDCARD_MUTATION_PROB));
+			this.maxConnections = (int)params.get(params.MAX_EDGES);
+			this.editEdges = (boolean)params.get(params.EDIT_EDGES);
+		}
+		
+		public void setObjectSpace(ArrayList<AbstractCpsObject> space){
+			objSpace = space;
+		}
+		
+		public void setEdgeMutationProb(double prob){
+			this.edgeMutationProb = prob;
+		}
+	}
+	
+}

+ 2 - 0
src/classes/AbstractCpsObject.java

@@ -75,6 +75,8 @@ public abstract class AbstractCpsObject {
 		setId(IdCounter.nextId());
 		setImage(obj.getImage());
 	}
+	
+	public abstract AbstractCpsObject makeCopy();
 
 	/**
 	 * Getter for the type of the Object.

+ 10 - 0
src/classes/CpsNode.java

@@ -24,7 +24,17 @@ public class CpsNode extends AbstractCpsObject {
 		this.setSav("CVS");
 		this.setId(IdCounter.nextId());
 	}
+	
+	public CpsNode(CpsNode node){
+		super(node);
+	}
+	
 	public String toString(){
 		return "Node ID:" + super.id;
 	}
+	
+	@Override
+	public AbstractCpsObject makeCopy() {
+		return new CpsNode(this);
+	}
 }

+ 5 - 0
src/classes/CpsUpperNode.java

@@ -205,5 +205,10 @@ public class CpsUpperNode extends AbstractCpsObject {
 		this.leftBorder = leftBorder;
 	}
 
+	@Override
+	public AbstractCpsObject makeCopy() {
+		return this;
+	}
+
 
 }

+ 5 - 0
src/classes/HolonBattery.java

@@ -184,4 +184,9 @@ public class HolonBattery extends AbstractCpsObject{
 		setImage(battery);
 		return battery;
 	}
+	
+	@Override
+	public HolonBattery makeCopy(){
+		return new HolonBattery(this);
+	}
 }

+ 5 - 0
src/classes/HolonObject.java

@@ -360,5 +360,10 @@ public class HolonObject extends AbstractCpsObject {
 
         return sb.toString();
     }
+    
+    @Override
+	public HolonObject makeCopy(){
+		return new HolonObject(this);
+	}
 
 }

+ 5 - 0
src/classes/HolonSwitch.java

@@ -309,4 +309,9 @@ public class HolonSwitch extends AbstractCpsObject implements LocalMode, GraphEd
 	public void setUseLocalPeriod(boolean state) {
 		this.localPeriodActive=state;
 	}
+	
+	@Override
+	public HolonSwitch makeCopy(){
+		return new HolonSwitch(this);
+	}
 }

+ 2 - 2
src/ui/controller/SimulationManager.java

@@ -49,7 +49,7 @@ public class SimulationManager {
 	 * @param m
 	 *            Model
 	 */
-	SimulationManager(Model m) {
+	public SimulationManager(Model m) {
 		model = m;
 	}
 	/**
@@ -58,7 +58,7 @@ public class SimulationManager {
 	 * @param timestep
 	 *            current Iteration
 	 */
-	void calculateStateForTimeStep(int timestep) {
+	public void calculateStateForTimeStep(int timestep) {
 		
 		
 		HashMap<CpsEdge, CableState> map = new HashMap<CpsEdge, CableState>();