Browse Source

GridVersion Milestone

Dominik Rieder 6 years ago
parent
commit
72027e2e69

+ 6 - 1
src/algorithms/geneticAlgorithm/Components/GAResultListener.java

@@ -2,7 +2,12 @@ package algorithms.geneticAlgorithm.Components;
 
 import java.util.ArrayList;
 
+import algorithms.geneticAlgorithm.holegGA.Components.HolegGeneration;
+import algorithms.geneticAlgorithm.holegGA.Components.HolegIndividual;
+
 public interface GAResultListener<I extends GAIndividual> {
 
-	public void populationCreated(int generation, ArrayList<I> population);
+	public void populationCreated(HolegGeneration holegGen);
+
+
 }

+ 34 - 1
src/algorithms/geneticAlgorithm/Components/GeneticAlgo.java

@@ -3,6 +3,8 @@ package algorithms.geneticAlgorithm.Components;
 import java.util.ArrayList;
 import java.util.Random;
 
+import algorithms.geneticAlgorithm.holegGA.Components.HolegIndividual;
+
 public class GeneticAlgo<I extends GAIndividual> {
 
 	public int popSize;
@@ -13,6 +15,8 @@ public class GeneticAlgo<I extends GAIndividual> {
 	public GACrossoverStrategy<I> reproducer;
 	public GAMutationStrategy<I> mutator;
 	public GAFittnessFunctionStrategy<I> fittnessFunction;
+	public double topPercent;
+	public double buttomPercent;
 	
 	public GeneticAlgo(GASelectionStrategy<I> selection, GACrossoverStrategy<I> crossover, GAMutationStrategy<I> mutator, 
 			GAFittnessFunctionStrategy<I> fittnessFkt, GAIndividualFactory<I> factory, int popSize){
@@ -25,11 +29,14 @@ public class GeneticAlgo<I extends GAIndividual> {
 		this.popSize = popSize;
 		
 		population = new ArrayList<I>();
+		topPercent = 0.1;
+		buttomPercent = 0.95;
 		
-		generateRandomPopulation();
+		//generateRandomPopulation();
 	}
 
 	public void generateRandomPopulation() {
+		population = new ArrayList<I>();
 		for(int i = 0; i < popSize; i++){
 			population.add(randomFactory.createRandomIndividual());
 			fittnessFunction.calculateFittness(population.get(i));
@@ -38,6 +45,12 @@ public class GeneticAlgo<I extends GAIndividual> {
 	
 	public void createNextGeneration(){
 		ArrayList<I> nextGen = new ArrayList<I>();
+		int topBound = (int) Math.ceil(topPercent * popSize);
+		population = sortPopulation(population);
+		nextGen.addAll(population.subList(0, topBound));
+		
+		int buttomBound = (int) Math.ceil(buttomPercent * popSize);
+		nextGen.addAll(population.subList(buttomBound, population.size()));
 		
 		selector.setCurrentPopulation(population);
 		while(nextGen.size() < popSize){
@@ -59,4 +72,24 @@ public class GeneticAlgo<I extends GAIndividual> {
 	public ArrayList<I> getPopulation(){
 		return population;
 	}
+	
+	public ArrayList<I> getSortedPopulation(){
+		return sortPopulation(population);
+	}
+	
+	public ArrayList<I> sortPopulation(ArrayList<I> individuals){
+		ArrayList<I> sortedList = new ArrayList<I>();
+		for(I 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;
+	}
 }

+ 114 - 0
src/algorithms/geneticAlgorithm/Components/Selections/TournamentRankSelection.java

@@ -0,0 +1,114 @@
+package algorithms.geneticAlgorithm.Components.Selections;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import algorithms.geneticAlgorithm.Components.GAIndividual;
+import algorithms.geneticAlgorithm.Components.GASelectionStrategy;
+
+public class TournamentRankSelection<I extends GAIndividual> implements GASelectionStrategy<I>{
+
+	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 TournamentRankSelection(){
+		currentPop = new ArrayList<I>();
+		tournamentSize = 1;
+		rng = new Random();
+	}
+	
+	public TournamentRankSelection(int tSize){
+		currentPop = new ArrayList<I>();
+		rng = new Random();
+		tournamentSize = tSize;
+	}
+	
+	@Override
+	public void setCurrentPopulation(ArrayList<I> population) {
+		currentPop = population;
+	}
+	
+	public void setTournamentSize(int size){
+		tournamentSize = size;
+	}
+
+	@Override
+	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++){
+			
+			Range range = new Range(maxRange, maxRange + tournamentSize - i);
+			tournamentWheel.add(range);
+			maxRange += tournamentSize - i;
+			/*
+			double currentProb = selectProb * Math.pow((1- selectProb), power);
+			Range range = new Range(maxRange, maxRange + currentProb);
+			tournamentWheel.add(range);
+			maxRange += currentProb;
+			power++;
+			*/
+		}
+	}
+
+}

+ 0 - 3
src/algorithms/geneticAlgorithm/holegGA/Components/HolegCrossover.java

@@ -27,8 +27,6 @@ public class HolegCrossover extends GACrossoverStrategy<HolegIndividual> {
 		
 		ArrayList<Integer> parent1NonOrgIndexes = parent1.getNonOriginIndexes();
 		int splitIdx = (int) Math.ceil((double)parent1NonOrgIndexes.size()/2);
-		child.addLogEntry("Object Split: " + splitIdx);
-		child.addLogEntry("none Org Indexes par1: " + parent1NonOrgIndexes.size());
 		
 		//HolonObjects
 		for(int i = 0; i < splitIdx; i++){
@@ -52,7 +50,6 @@ public class HolegCrossover extends GACrossoverStrategy<HolegIndividual> {
 		
 		//HolonEdges
 		splitIdx = (int) Math.ceil((double)parent1.getEdges().size()/2);
-		child.addLogEntry("Edge Split: " + splitIdx);
 		for(int k = 0; k < splitIdx; k++){
 			int posA = parent1.getEdges().get(k).aPos;
 			int posB = parent1.getEdges().get(k).bPos;

+ 45 - 3
src/algorithms/geneticAlgorithm/holegGA/Components/HolegFittnessFkt.java

@@ -1,25 +1,67 @@
 package algorithms.geneticAlgorithm.holegGA.Components;
 
+import java.util.ArrayList;
+
+import ui.controller.Control;
+import ui.controller.SimulationManager;
+import ui.model.Model;
 import classes.AbstractCpsObject;
 import classes.HolonObject;
 import algorithms.geneticAlgorithm.Components.GAFittnessFunctionStrategy;
 import algorithms.geneticAlgorithm.Components.GAIndividual;
 
 public class HolegFittnessFkt implements GAFittnessFunctionStrategy<HolegIndividual>{
+	
+	Control controller;
+	Model model;
+	SimulationManager simManager;
+	
+	public HolegFittnessFkt(Control controller){
+		//this.controller = controller;
+		//model = controller.getModel();
+		//simManager = controller.getSimManager();
+		model = new Model();
+		simManager = new SimulationManager(model);
+	}
 
 	@Override
-	public double calculateFittness(HolegIndividual candidate) {
+	public double calculateFittness(HolegIndividual candidate){
+		model.getObjectsOnCanvas().clear();
+		model.getEdgesOnCanvas().clear();
+		model.getObjectsOnCanvas().addAll(candidate.getObjects());
+		model.getEdgesOnCanvas().addAll(candidate.getEdges());
+		simManager.calculateStateForTimeStep(model.getCurIteration());
+		
 		double fittness = 0;
 		for(AbstractCpsObject abs : candidate.getObjects()){
 			if(abs instanceof HolonObject){
+				
+				switch (((HolonObject) abs).getState()){
+					
+				case HolonObject.SUPPLIED : 
+					fittness += 10;
+					break;
+						
+				case HolonObject.NOT_SUPPLIED :
+					fittness -= 5;
+					break;
+					
+				}
+				/*
 				if(((HolonObject) abs).getState() == HolonObject.SUPPLIED){
 					fittness += 100;
 				}
+				*/
 			}
 		}
+		fittness -= candidate.getEdges().size()*0.1;
 		candidate.setFittness(fittness);
-		candidate.addLogEntry("Fittness: " + fittness);
+		//candidate.addLogEntry("Fittness: " + fittness);
 		return fittness;
 	}
-
+	
+	public Model getModel(){
+		return model;
+	}
+		
 }

+ 35 - 0
src/algorithms/geneticAlgorithm/holegGA/Components/HolegFittnessScenario.java

@@ -0,0 +1,35 @@
+package algorithms.geneticAlgorithm.holegGA.Components;
+
+import ui.controller.Control;
+import ui.controller.SimulationManager;
+import ui.model.Model;
+import algorithms.geneticAlgorithm.Components.GAFittnessFunctionStrategy;
+
+public class HolegFittnessScenario implements GAFittnessFunctionStrategy<HolegIndividual>{
+
+	HolegFittnessFkt singleFkt;
+	Control controller;
+	Model model;
+	SimulationManager simManager;
+		
+	public HolegFittnessScenario(Control controller) {
+		singleFkt = new HolegFittnessFkt(controller);
+		model = singleFkt.getModel();
+		
+	}
+	
+	@Override
+	public double calculateFittness(HolegIndividual candidate) {
+		double fittness = 0;
+		for(int i = 0; i < 100; i++){
+			model.setCurIteration(i);
+			fittness += singleFkt.calculateFittness(candidate);
+		}
+		fittness = (int)fittness;
+		fittness =	fittness * 0.01;
+		candidate.setFittness(fittness);
+		candidate.addLogEntry("Fittness: " + fittness);
+		return fittness;
+	}
+
+}

+ 83 - 0
src/algorithms/geneticAlgorithm/holegGA/Components/HolegGeneration.java

@@ -0,0 +1,83 @@
+package algorithms.geneticAlgorithm.holegGA.Components;
+
+import java.util.ArrayList;
+
+public class HolegGeneration {
+	
+	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 = "";
+		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;
+	}
+
+}

+ 40 - 4
src/algorithms/geneticAlgorithm/holegGA/Components/HolegIndividual.java

@@ -2,6 +2,7 @@ package algorithms.geneticAlgorithm.holegGA.Components;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Set;
 
 import classes.AbstractCpsObject;
 import classes.CpsNode;
@@ -10,7 +11,6 @@ import algorithms.geneticAlgorithm.holegGA.GAEdge;
 
 public class HolegIndividual extends GAIndividual {
 	
-	private ArrayList<AbstractCpsObject> holonObjects;
 	private ArrayList<GAEdge> holonEdges;
 	public ArrayList<Integer> indexes;
 	public ArrayList<Integer> originIndexes;
@@ -25,7 +25,6 @@ public class HolegIndividual extends GAIndividual {
 	private int lastIndex;
 	
 	public HolegIndividual(ArrayList<AbstractCpsObject> originObjects){
-		holonObjects = new  ArrayList<AbstractCpsObject>();
 		holonEdges = new ArrayList<GAEdge>();
 		indexes = new ArrayList<Integer>();
 		originIndexes = new ArrayList<Integer>();
@@ -44,6 +43,29 @@ public class HolegIndividual extends GAIndividual {
 		}
 	}
 	
+	public HolegIndividual(HolegIndividual indi){
+		holonEdges = new ArrayList<GAEdge>();
+		holonEdges.addAll(indi.getEdges());
+		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 ArrayList<HolegIndividual> getParents(){
 		return parents;
 	}
@@ -57,9 +79,9 @@ public class HolegIndividual extends GAIndividual {
 	
 	public void setId(int Gen, int pos){
 		if(Gen > 0){
-			id = "Generation_" + Gen + " Position_" + pos;
+			id = "Generation_" + Gen + " Rank_" + pos;
 		}else{
-			id = "Generation_Origin" + " Position_" + pos;
+			id = "Generation_Original";
 		}
 	}
 	
@@ -125,6 +147,11 @@ public class HolegIndividual extends GAIndividual {
 		//indexToObjectMap.put(index, obj);
 	}
 	
+	public void removeObject(int index){
+		indexToObjectMap.remove(index);
+		indexes.remove((Object)index);
+	}
+	
 	public void addIndex(int index){
 		for(int i = 0; i < indexes.size(); i++){
 			if(index < indexes.get(i)){
@@ -170,5 +197,14 @@ public class HolegIndividual extends GAIndividual {
 	public void addLogEntry(String entry){
 		log += "\n" + entry;
 	}
+	
+	public int getAvailableIndex(){
+		for(int i = 0; i <= indexes.size(); i++){
+			if(!indexes.contains(i)){
+				return i;
+			}
+		}
+		return -1;
+	}
 
 }

+ 203 - 0
src/algorithms/geneticAlgorithm/holegGA/Components/HolegMutation.java

@@ -1,12 +1,215 @@
 package algorithms.geneticAlgorithm.holegGA.Components;
 
+import java.util.ArrayList;
+import java.util.Collections;
+
+import classes.AbstractCpsObject;
+import classes.CpsEdge;
+import classes.CpsNode;
+import classes.HolonBattery;
+import classes.HolonObject;
+import classes.HolonSwitch;
 import algorithms.geneticAlgorithm.Components.GAMutationStrategy;
+import algorithms.geneticAlgorithm.holegGA.GAEdge;
 
 public class HolegMutation extends GAMutationStrategy<HolegIndividual>{
+	
+	public final int CHANGE_EDGE = 0;
+	public final int ADD_EDGE = 1;
+	public final int REMOVE_EDGE = 2;
+	public final int CHANGE_OBJECT = 3;
+	public final int ADD_OBJECT = 4;
+	public final int REMOVE_OBJECT = 5;
+	ArrayList<AbstractCpsObject> objSpace;
+	
+	public HolegMutation(){
+		super();
+	}
+	
+	public HolegMutation(double prob){
+		super(prob);
+	}
 
 	@Override
 	public HolegIndividual mutateIndividual(HolegIndividual mutant) {
+		if(rng.nextDouble() < mutationProb){
+			switch(rng.nextInt(6)){
+			case CHANGE_EDGE : 
+				changeEdge(mutant);
+				break;		
+			case ADD_EDGE : 
+				addEdge(mutant);
+				break;
+			case REMOVE_EDGE : 
+				removeEdge(mutant);
+				break;
+			case CHANGE_OBJECT : 
+				changeObject(mutant);
+				break;
+			case ADD_OBJECT : 
+				addObject(mutant);
+				break;
+			case REMOVE_OBJECT : 
+				removeObject(mutant);
+				break;
+			}
+		}
 		return mutant;
 	}
 
+	public void removeObject(HolegIndividual mutant) {
+		if(mutant.getNonOriginIndexes().size() > 0){
+			int removeIdx = rng.nextInt(mutant.getNonOriginIndexes().size());
+			removeIdx = mutant.getNonOriginIndexes().get(removeIdx);
+			ArrayList<CpsEdge> connections = new ArrayList<CpsEdge>();
+			connections.addAll(mutant.getObjectWithIndex(removeIdx).getConnections());
+			for(CpsEdge e : connections){
+				/*
+				if(e.getA() != mutant.getObjectWithIndex(mutant.getNonOriginIndexes().get(removeIdx))){
+					e.getA().getConnections().remove(e);
+				}else{
+					e.getB().getConnections().remove(e);
+				}
+				*/
+		
+				e.getA().getConnections().remove(e);
+				e.getB().getConnections().remove(e);
+		
+			}
+			
+			ArrayList<GAEdge> edgesToRemove = new ArrayList<GAEdge>();
+			for(GAEdge  gE : mutant.getEdges()){
+				if(gE.aPos == removeIdx || gE.bPos == removeIdx){
+					edgesToRemove.add(gE);
+				}
+			}
+			mutant.getEdges().removeAll(edgesToRemove);
+			
+			mutant.addLogEntry("Object wit ID " + mutant.indexToObjectMap.get(removeIdx).getId() + " removed");
+			mutant.removeObject(removeIdx);
+		}
+	}
+
+	public void addObject(HolegIndividual mutant) {
+		int objSpaceIdx = rng.nextInt(objSpace.size());
+		int addIndex = mutant.getAvailableIndex();
+		
+		
+		AbstractCpsObject newObj = null;
+		AbstractCpsObject object = objSpace.get(objSpaceIdx);
+		if(object instanceof HolonObject){
+			newObj = new HolonObject(object);
+		}else if(object instanceof HolonSwitch){
+			newObj = new HolonSwitch(object);
+		}else if(object instanceof HolonBattery){
+			newObj = new HolonBattery(object);
+		}else if(object == null){
+			newObj = new CpsNode("Node");
+		}
+		
+		if(mutant.getIndexes().size() > 0){
+			int indexB = mutant.getIndexes().get(rng.nextInt(mutant.getIndexes().size()));
+			mutant.addObjectWithIdx(newObj, addIndex);
+			mutant.addEdge(addIndex, indexB);
+			mutant.addLogEntry("Object with ID " + newObj.getId() + " and Edge between "
+					+ mutant.indexToObjectMap.get(indexB).getId() + " and " + newObj.getId() + " added");
+		}else{
+			mutant.addObjectWithIdx(newObj, addIndex);
+			mutant.addLogEntry("Object with ID " + newObj.getId() + " added");
+		}
+	}
+
+	public void changeObject(HolegIndividual mutant) {
+		if(mutant.getNonOriginIndexes().size() > 0){
+			int changeIdx = rng.nextInt(mutant.getNonOriginIndexes().size());
+			changeIdx = mutant.getNonOriginIndexes().get(changeIdx);
+	
+			AbstractCpsObject newObj = null;
+			AbstractCpsObject absObj = objSpace.get(rng.nextInt(objSpace.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 == null){
+				newObj = new CpsNode("Node");
+			}
+		
+			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);
+				}
+			}
+			mutant.indexToObjectMap.put(changeIdx, newObj);
+			mutant.addLogEntry("Object changed");
+			//LogEntry notwendig
+		}
+	}
+
+	public void removeEdge(HolegIndividual mutant) {
+		if(mutant.getEdges().size() > 0){
+			int edgeIdx = rng.nextInt(mutant.getEdges().size());
+			CpsEdge toRemove = mutant.getEdges().get(edgeIdx);
+			toRemove.getA().getConnections().remove(toRemove);
+			toRemove.getB().getConnections().remove(toRemove);
+			mutant.getEdges().remove(toRemove);
+			mutant.addLogEntry("Edge between " + toRemove.getA().getId() + " and "
+				+ toRemove.getB().getId() + " removed");
+		}
+	}
+
+	public void addEdge(HolegIndividual mutant) {
+		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 between " + mutant.indexToObjectMap.get(aPos).getId() + 
+				" and " + mutant.indexToObjectMap.get(bPos).getId() + " added");
+		}
+	}
+
+	public void changeEdge(HolegIndividual mutant) {
+		if(mutant.getEdges().size() > 0){
+			int edgeIdx = rng.nextInt(mutant.getEdges().size());
+			CpsEdge toChange = mutant.getEdges().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));
+					mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
+				}else{
+					toChange.getB().getConnections().remove(toChange);
+					mutant.getEdges().remove(toChange);
+				}
+			}else{
+				toChange.getB().getConnections().remove(toChange);
+				if(toChange.getA() != mutant.getObjectWithIndex(randomIndex)){
+					toChange.setB(mutant.getObjectWithIndex(randomIndex));
+					mutant.getObjectWithIndex(randomIndex).getConnections().add(toChange);
+				}else{
+					toChange.getA().getConnections().remove(toChange);
+					mutant.getEdges().remove(toChange);
+				}
+			}
+			mutant.addLogEntry("Edge Changed");
+		}
+		
+	}
+	
+	public void setObjectSpace(ArrayList<AbstractCpsObject> space){
+		objSpace = space;
+	}
+
 }

+ 96 - 15
src/algorithms/geneticAlgorithm/holegGA/GenAlgoHandler.java

@@ -9,9 +9,16 @@ import classes.Position;
 import ui.controller.Control;
 import ui.model.Model;
 import algorithms.geneticAlgorithm.Components.GAResultListener;
+import algorithms.geneticAlgorithm.Components.GeneticAlgo;
+import algorithms.geneticAlgorithm.Components.Selections.TournamentRankSelection;
+import algorithms.geneticAlgorithm.Components.Selections.TournamentSelectionStrategy;
 import algorithms.geneticAlgorithm.holegGA.Components.HolegCrossover;
 import algorithms.geneticAlgorithm.holegGA.Components.HolegFactory;
+import algorithms.geneticAlgorithm.holegGA.Components.HolegFittnessFkt;
+import algorithms.geneticAlgorithm.holegGA.Components.HolegFittnessScenario;
+import algorithms.geneticAlgorithm.holegGA.Components.HolegGeneration;
 import algorithms.geneticAlgorithm.holegGA.Components.HolegIndividual;
+import algorithms.geneticAlgorithm.holegGA.Components.HolegMutation;
 
 public class GenAlgoHandler {
 	
@@ -20,43 +27,101 @@ public class GenAlgoHandler {
 	Control controller;
 	Model model;
 	int genCount;
+	public int popSize;
+	public int tournamentSize;
+	public double tournamentProb;
 	boolean onlyNodes;
+	GeneticAlgo<HolegIndividual> holegGA;
+	TournamentRankSelection<HolegIndividual> tRS;
+	HolegMutation hM;
+	HolegCrossover hC;
+	ArrayList<AbstractCpsObject> objSpace;
 	
 	public GenAlgoHandler(Control controller, Model model){
 		this.controller = controller;
 		this.model = model;
 		genCount = 1;
-		ArrayList<AbstractCpsObject> objSpace = new ArrayList<AbstractCpsObject>();
+		popSize = 100;
+		objSpace = new ArrayList<AbstractCpsObject>();
 		for(Category cat : model.getCategories()){
 			for(AbstractCpsObject obj : cat.getObjects()){
 				objSpace.add(obj);
 			}
 		}
 		ArrayList<AbstractCpsObject> origin = model.getObjectsOnCanvas();
-		factory = new HolegFactory(objSpace, 5, 5);
+		factory = new HolegFactory(objSpace, 0, 0);
 		factory.originObjects = origin;
 		onlyNodes = false;
+		
+		hC = new HolegCrossover();
+		//HolegFittnessFkt hF = new HolegFittnessFkt(controller);
+		HolegFittnessScenario hF = new HolegFittnessScenario(controller);
+		hM = new HolegMutation(0.01);
+		hM.setObjectSpace(objSpace);
+		tRS = new TournamentRankSelection<HolegIndividual>();
+		holegGA = new GeneticAlgo<HolegIndividual>(tRS, hC, hM, hF, factory, popSize);
 	}
 	
 	public void createGeneration(int objAmount, int edgeAmount){
 		factory.maxObjects = objAmount;
 		factory.maxConnections = edgeAmount;
 		factory.onlyNodes = onlyNodes;
-		ArrayList<HolegIndividual> population = new ArrayList<HolegIndividual>();
-		for(int i = 1; i <= 2; i++){
-			population.add(factory.createRandomIndividual());
+		holegGA.popSize = popSize;
+		tRS.tournamentSize = tournamentSize;
+		
+		if(genCount == 1){
+			holegGA.generateRandomPopulation();
+			HolegGeneration holegGen = new HolegGeneration(genCount);
+			holegGen.setGeneration(holegGA.getSortedPopulation());
+			addPopulationListeners(holegGen);
+			//addPopulationListeners(genCount, sortPopulation(holegGA.getPopulation()));
+			//addPopulationListeners(genCount, holegGA.getPopulation());
+		}else{
+			holegGA.createNextGeneration();
+			HolegGeneration holegGen = new HolegGeneration(genCount);
+			holegGen.setGeneration(holegGA.getSortedPopulation());
+			addPopulationListeners(holegGen);
+			//addPopulationListeners(genCount, sortPopulation(holegGA.getPopulation()));
 		}
-		addPopulationListeners(genCount, population);
+		genCount++;
+	}
+	
+	public void mutationTest(int objAmount, int edgeAmount){
+		factory.maxObjects = objAmount;
+		factory.maxConnections = edgeAmount;
+		factory.onlyNodes = onlyNodes;
+		HolegIndividual parent = factory.createRandomIndividual();
+		ArrayList<HolegIndividual> jo = new ArrayList<HolegIndividual>();
+		jo.add(parent);
+		jo.add(parent);
+		HolegGeneration joGen = new HolegGeneration(genCount);
+		joGen.setGeneration(jo);
+		addPopulationListeners(joGen);
 		genCount++;
 		
-		ArrayList<HolegIndividual> children = new ArrayList<HolegIndividual>();
-		HolegCrossover hC = new HolegCrossover();
-		//for(int j = 1; j <= 2; j++){
-			children.addAll(hC.crossOver(population));
-		//}
-		addPopulationListeners(genCount, children);
+		ArrayList<HolegIndividual> jo2 = new ArrayList<HolegIndividual>();
+		HolegIndividual removeObject = hC.crossOver(jo).get(0);
+		HolegIndividual addObject = hC.crossOver(jo).get(0);
+		HolegIndividual changeObject = hC.crossOver(jo).get(0);
+		HolegIndividual removeEdge = hC.crossOver(jo).get(0);
+		HolegIndividual addEdge = hC.crossOver(jo).get(0);
+		HolegIndividual changeEdge = hC.crossOver(jo).get(0);
+		hM.removeObject(removeObject);
+		hM.addObject(addObject);
+		hM.changeObject(changeObject);
+		hM.removeEdge(removeEdge);
+		hM.addEdge(addEdge);
+		hM.changeEdge(changeEdge);
+		jo2.add(removeObject);
+		jo2.add(addObject);
+		jo2.add(changeObject);
+		jo2.add(removeEdge);
+		jo2.add(addEdge);
+		jo2.add(changeEdge);
+		HolegGeneration jo2Gen = new HolegGeneration(genCount);
+		jo2Gen.setGeneration(jo2);
+		addPopulationListeners(jo2Gen);
 		genCount++;
-
 	}
 	
 	public void drawIndividual(HolegIndividual hI){
@@ -142,10 +207,26 @@ public class GenAlgoHandler {
 		listeners.add(listener);
 	}
 	
-	public void addPopulationListeners(int generation, ArrayList<HolegIndividual> population){
+	public void addPopulationListeners(HolegGeneration holegGen){
 		for(GAResultListener<HolegIndividual> listener : listeners){
-			listener.populationCreated(generation, population);
+			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;
 	}
 	
 	

+ 74 - 20
src/algorithms/geneticAlgorithm/holegGA/GenAlgoWindow.java

@@ -25,6 +25,7 @@ import ui.view.UnitGraph;
 import javax.swing.JButton;
 
 import algorithms.geneticAlgorithm.Components.GAResultListener;
+import algorithms.geneticAlgorithm.holegGA.Components.HolegGeneration;
 import algorithms.geneticAlgorithm.holegGA.Components.HolegIndividual;
 
 import java.awt.event.ActionListener;
@@ -49,12 +50,14 @@ public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
 	DefaultTreeModel treeModel;
 	DefaultMutableTreeNode treeRoot;
 	HashMap<DefaultMutableTreeNode, HolegIndividual> treeIndiHashmap;
-
 	GenAlgoHandler algoHandler;
 	private JTextField objectAmountField;
 	private JTextField edgeAmountField;
 	private JCheckBox chckbxOnlyNodes;
 	private JTextArea logArea;
+	private JTextField popSizeField;
+	private JTextField tournamentSizeField;
+	private JTextField tournamentProbField;
 	/**
 	 * Create the application.
 	 */
@@ -69,7 +72,9 @@ public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
 		HolegIndividual originIndividual = new HolegIndividual(model.getObjectsOnCanvas());
 		ArrayList<HolegIndividual> originPopulation = new ArrayList<HolegIndividual>();
 		originPopulation.add(originIndividual);
-		populationCreated(-1, originPopulation);
+		HolegGeneration originGen = new HolegGeneration(-1);
+		originGen.setGeneration(originPopulation);
+		populationCreated(originGen);
 		
 	}
 
@@ -78,7 +83,7 @@ public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
 	 */
 	private void initialize() {
 		frame = new JFrame();
-		frame.setBounds(100, 100, 450, 409);
+		frame.setBounds(100, 100, 450, 520);
 		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
 		frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.X_AXIS));
 		
@@ -107,12 +112,14 @@ public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
 		rightSplitPane.setLeftComponent(panel);
 		
 		JButton btnCreategeneration = new JButton("createGeneration");
-		btnCreategeneration.setBounds(44, 11, 117, 23);
+		btnCreategeneration.setBounds(10, 11, 117, 23);
 		btnCreategeneration.addActionListener(new ActionListener() {
 			public void actionPerformed(ActionEvent arg0) {
 				int objAmount = Integer.parseInt(objectAmountField.getText());
 				int edgeAmount = Integer.parseInt(edgeAmountField.getText());
 				algoHandler.onlyNodes = chckbxOnlyNodes.isSelected();
+				algoHandler.popSize = Integer.parseInt(popSizeField.getText());
+				algoHandler.tournamentSize = Integer.parseInt(tournamentSizeField.getText());
 				algoHandler.createGeneration(objAmount, edgeAmount);
 			}
 		});
@@ -120,33 +127,77 @@ public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
 		
 		objectAmountField = new JTextField();
 		objectAmountField.setText("0");
-		objectAmountField.setBounds(89, 45, 86, 20);
+		objectAmountField.setBounds(111, 45, 86, 20);
 		panel.add(objectAmountField);
 		objectAmountField.setColumns(10);
 		panel.add(btnCreategeneration);
 		
 		edgeAmountField = new JTextField();
 		edgeAmountField.setText("0");
-		edgeAmountField.setBounds(89, 76, 86, 20);
+		edgeAmountField.setBounds(111, 76, 86, 20);
 		panel.add(edgeAmountField);
 		edgeAmountField.setColumns(10);
 		
 		JLabel lblMaxObjects = new JLabel("Max Objects");
-		lblMaxObjects.setBounds(10, 48, 69, 14);
+		lblMaxObjects.setBounds(10, 48, 91, 14);
 		panel.add(lblMaxObjects);
 		
 		JLabel lblMaxEdges = new JLabel("Max Edges");
-		lblMaxEdges.setBounds(10, 79, 69, 14);
+		lblMaxEdges.setBounds(10, 79, 91, 14);
 		panel.add(lblMaxEdges);
 		
 		chckbxOnlyNodes = new JCheckBox("\r\n");
-		chckbxOnlyNodes.setBounds(89, 103, 25, 23);
+		chckbxOnlyNodes.setBounds(121, 103, 25, 23);
 		panel.add(chckbxOnlyNodes);
 		
 		JLabel lblOnlyNodes = new JLabel("Only Nodes?");
-		lblOnlyNodes.setBounds(10, 107, 69, 14);
+		lblOnlyNodes.setBounds(10, 107, 91, 14);
 		panel.add(lblOnlyNodes);
 		
+		popSizeField = new JTextField();
+		popSizeField.setText("100");
+		popSizeField.setBounds(111, 133, 86, 20);
+		panel.add(popSizeField);
+		popSizeField.setColumns(10);
+		
+		tournamentSizeField = new JTextField();
+		tournamentSizeField.setText("30");
+		tournamentSizeField.setBounds(111, 164, 86, 20);
+		panel.add(tournamentSizeField);
+		tournamentSizeField.setColumns(10);
+		
+		tournamentProbField = new JTextField();
+		tournamentProbField.setText("0.8");
+		tournamentProbField.setBounds(111, 195, 86, 20);
+		panel.add(tournamentProbField);
+		tournamentProbField.setColumns(10);
+		
+		JLabel lblPopulationSize = new JLabel("Population Size");
+		lblPopulationSize.setBounds(10, 136, 91, 14);
+		panel.add(lblPopulationSize);
+		
+		JLabel lblTournamentSize = new JLabel("Tournament Size");
+		lblTournamentSize.setBounds(10, 167, 91, 14);
+		panel.add(lblTournamentSize);
+		
+		JLabel lblTournamentProb = new JLabel("Tournament Prob");
+		lblTournamentProb.setBounds(10, 198, 91, 14);
+		panel.add(lblTournamentProb);
+		
+		JButton btnMutation = new JButton("mutation");
+		btnMutation.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				int objAmount = Integer.parseInt(objectAmountField.getText());
+				int edgeAmount = Integer.parseInt(edgeAmountField.getText());
+				algoHandler.onlyNodes = chckbxOnlyNodes.isSelected();
+				algoHandler.popSize = Integer.parseInt(popSizeField.getText());
+				algoHandler.tournamentSize = Integer.parseInt(tournamentSizeField.getText());
+				algoHandler.mutationTest(objAmount, edgeAmount);
+			}
+		});
+		btnMutation.setBounds(137, 11, 89, 23);
+		panel.add(btnMutation);
+		
 		logArea = new JTextArea();
 		rightSplitPane.setRightComponent(logArea);
 		
@@ -156,7 +207,7 @@ public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
 		         TreePath selPath = genTree.getPathForLocation(e.getX(), e.getY());
 		         if(selRow != -1) {
 		             if(e.getClickCount() == 1) {
-		                 //mySingleClick(selRow, selPath);
+		                 nodeSingleClick(selRow, selPath);
 		             }
 		             else if(e.getClickCount() == 2) {
 		                 nodeDoubleClick(selRow, selPath);
@@ -168,28 +219,31 @@ public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
 		
 	}
 	
+	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.drawIndividual(treeIndiHashmap.get(node));
 			logArea.setText(treeIndiHashmap.get(node).log);
 		}
-		
 	}
 	
 
 	@Override
-	public void populationCreated(int generation, ArrayList<HolegIndividual> population) {
-		DefaultMutableTreeNode genNode;
-		if(! (generation == -1)){
-			genNode = new DefaultMutableTreeNode("Generation " + generation);
-		}else{
-			genNode = new DefaultMutableTreeNode("Origin Network");
-		}
+	public void populationCreated(HolegGeneration holegGen) {
+		DefaultMutableTreeNode genNode = new DefaultMutableTreeNode(holegGen);
 		
+		ArrayList<HolegIndividual> population = holegGen.getGeneration();
 		for(int i = 0; i < population.size(); i++){
 			DefaultMutableTreeNode child = new DefaultMutableTreeNode("Individual " + i);
-			population.get(i).setId(generation, i);
+			population.get(i).setId(holegGen.getGenCount(), i);
 			treeIndiHashmap.put(child, population.get(i));
 			genNode.add(child);
 		}

+ 7 - 4
src/ui/controller/SimulationManager.java

@@ -50,7 +50,7 @@ public class SimulationManager {
 	 * @param m
 	 *            Model
 	 */
-	SimulationManager(Model m) {
+	public SimulationManager(Model m) {
 		canvas = null;
 		model = m;
 		subNets = new ArrayList<>();
@@ -63,7 +63,7 @@ public class SimulationManager {
 	 * @param x
 	 *            current Iteration
 	 */
-	void calculateStateForTimeStep(int x) {
+	public void calculateStateForTimeStep(int x) {
 		reset();
 		timeStep = x;
 		searchForSubNets();
@@ -334,8 +334,11 @@ public class SimulationManager {
 				}
 			}
 		}
-		canvas.repaint();
-		flexPane.recalculate();
+		if(canvas != null){
+			canvas.repaint();
+			flexPane.recalculate();
+		}
+		
 	}
 
 	private void calculation(int x, SubNet singleSubNet, float production, float consumption, float energySurplus,