Browse Source

Random Generator in Holeg integriert

Dominik Rieder 6 years ago
parent
commit
c3b7203c52

+ 8 - 0
src/algorithms/geneticAlgorithm/Components/GAResultListener.java

@@ -0,0 +1,8 @@
+package algorithms.geneticAlgorithm.Components;
+
+import java.util.ArrayList;
+
+public interface GAResultListener<I extends GAIndividual> {
+
+	public void populationCreated(int generation, ArrayList<I> population);
+}

+ 17 - 0
src/algorithms/geneticAlgorithm/holegGA/GAEdge.java

@@ -0,0 +1,17 @@
+package algorithms.geneticAlgorithm.holegGA;
+
+import classes.AbstractCpsObject;
+import classes.CpsEdge;
+
+public class GAEdge extends CpsEdge {
+	
+	int aPos;
+	int bPos;
+	
+	public GAEdge(int a, int b, AbstractCpsObject nodeA, AbstractCpsObject nodeB){
+		super(nodeA,nodeB, CAPACITY_INFINITE);
+		aPos = a;
+		bPos = b;
+	}
+
+}

+ 94 - 0
src/algorithms/geneticAlgorithm/holegGA/GenAlgoHandler.java

@@ -0,0 +1,94 @@
+package algorithms.geneticAlgorithm.holegGA;
+
+import java.util.ArrayList;
+
+import classes.AbstractCpsObject;
+import classes.Category;
+import classes.CpsEdge;
+import classes.Position;
+import ui.controller.Control;
+import ui.model.Model;
+import algorithms.geneticAlgorithm.Components.GAResultListener;
+
+public class GenAlgoHandler {
+	
+	ArrayList<GAResultListener<HolegIndividual>> listeners = new ArrayList<GAResultListener<HolegIndividual>>();
+	HolegFactory factory;
+	Control controller;
+	Model model;
+	int genCount;
+	
+	public GenAlgoHandler(Control controller, Model model){
+		this.controller = controller;
+		this.model = model;
+		genCount = 1;
+		ArrayList<AbstractCpsObject> objSpace = new ArrayList<AbstractCpsObject>();
+		for(Category cat : model.getCategories()){
+			for(AbstractCpsObject obj : cat.getObjects()){
+				objSpace.add(obj);
+			}
+		}
+		factory = new HolegFactory(objSpace, 5, 5);
+	}
+	
+	public void createGeneration(){
+		ArrayList<HolegIndividual> population = new ArrayList<HolegIndividual>();
+		for(int i = 1; i <= 2; i++){
+			population.add(factory.createRandomIndividual());
+		}
+		addPopulationListeners(genCount, population);
+		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);
+		genCount++;
+	}
+	
+	public void drawIndividual(HolegIndividual hI){
+		model.setObjectsOnCanvas(new ArrayList<AbstractCpsObject>());
+		model.setEdgesOnCanvas(new ArrayList<CpsEdge>());
+		
+		int xBound = (int) Math.ceil(Math.sqrt(hI.holonObjects.size()));
+		int row = -1;
+		
+		int x = 50;
+		int y = 50;
+		int dist = 200;
+		boolean isX = true;
+		
+		for(int i = 0; i < hI.holonObjects.size(); i++){
+		//for(AbstractCpsObject abs : hI.holonObjects){
+			AbstractCpsObject abs = hI.holonObjects.get(i);
+			
+			
+			
+			if(i % xBound == 0){
+				row++;
+			}
+			
+			abs.setPosition(new Position(((i % xBound)* dist) + x , (row * dist) + y));
+			controller.addObjectCanvas(abs);
+		}
+		
+		for(int j = 0; j < hI.holonEdges.size(); j++){
+			controller.addEdgeOnCanvas(hI.holonEdges.get(j));
+		}
+	}
+	
+	public void addListener(GAResultListener<HolegIndividual> listener){
+		listeners.add(listener);
+	}
+	
+	public void addPopulationListeners(int generation, ArrayList<HolegIndividual> population){
+		for(GAResultListener<HolegIndividual> listener : listeners){
+			listener.populationCreated(generation, population);
+		}
+	}
+	
+	
+
+}

+ 32 - 0
src/algorithms/geneticAlgorithm/holegGA/GenAlgoInit.java

@@ -0,0 +1,32 @@
+package algorithms.geneticAlgorithm.holegGA;
+
+import java.util.ArrayList;
+
+import classes.AbstractCpsObject;
+import classes.Category;
+import classes.CpsEdge;
+import classes.HolonBattery;
+import classes.HolonObject;
+import classes.HolonSwitch;
+import classes.Position;
+import ui.controller.Control;
+import ui.model.Model;
+
+public class GenAlgoInit {
+	
+	Control controller;
+	Model model;
+	GenAlgoWindow window;
+
+	public GenAlgoInit(Control controller, Model model){
+		this.controller = controller;
+		this.model = model;
+	}
+	
+	public void start(){
+		
+		window = new GenAlgoWindow(controller, model);
+		window.frame.setVisible(true);
+	}
+	
+}

+ 148 - 0
src/algorithms/geneticAlgorithm/holegGA/GenAlgoWindow.java

@@ -0,0 +1,148 @@
+package algorithms.geneticAlgorithm.holegGA;
+
+import java.awt.EventQueue;
+
+import javax.swing.JFrame;
+import javax.swing.JSplitPane;
+
+import java.awt.BorderLayout;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.BoxLayout;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.JPanel;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+
+import ui.controller.Control;
+import ui.model.Model;
+import ui.view.MyCanvas;
+import ui.view.UnitGraph;
+
+import javax.swing.JButton;
+
+import algorithms.geneticAlgorithm.Components.GAResultListener;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+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.JTextField;
+
+public class GenAlgoWindow implements GAResultListener<HolegIndividual> {
+
+	JFrame frame;
+	Control controller;
+	Model model;
+	JTree genTree;
+	DefaultTreeModel treeModel;
+	DefaultMutableTreeNode treeRoot;
+	HashMap<DefaultMutableTreeNode, HolegIndividual> treeIndiHashmap;
+
+	GenAlgoHandler algoHandler;
+	private JTextField textField;
+	/**
+	 * 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();
+		
+	}
+
+	/**
+	 * Initialize the contents of the frame.
+	 */
+	private void initialize() {
+		frame = new JFrame();
+		frame.setBounds(100, 100, 450, 409);
+		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.X_AXIS));
+		
+	
+		JSplitPane mainSplitPane = new JSplitPane();
+		mainSplitPane.setResizeWeight(0.3);
+		frame.getContentPane().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.5);
+		rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
+		mainSplitPane.setRightComponent(rightSplitPane);
+		
+		JPanel panel = new JPanel();
+		rightSplitPane.setLeftComponent(panel);
+		
+		JButton btnCreategeneration = new JButton("createGeneration");
+		btnCreategeneration.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				algoHandler.createGeneration();
+			}
+		});
+		
+		textField = new JTextField();
+		panel.add(textField);
+		textField.setColumns(10);
+		panel.add(btnCreategeneration);
+		
+		 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) {
+		                 //mySingleClick(selRow, selPath);
+		             }
+		             else if(e.getClickCount() == 2) {
+		                 nodeDoubleClick(selRow, selPath);
+		             }
+		         }
+		     }
+		 };
+		 genTree.addMouseListener(ml);
+		
+	}
+	
+	public void nodeDoubleClick(int selRow, TreePath selPath){
+		DefaultMutableTreeNode node = (DefaultMutableTreeNode)selPath.getLastPathComponent();
+		if(treeIndiHashmap.get(node) != null){
+			algoHandler.drawIndividual(treeIndiHashmap.get(node));
+		}
+		
+	}
+	
+
+	@Override
+	public void populationCreated(int generation, ArrayList<HolegIndividual> population) {
+		DefaultMutableTreeNode genNode = new DefaultMutableTreeNode("Generation " + generation);
+		
+		for(int i = 0; i < population.size(); i++){
+			DefaultMutableTreeNode child = new DefaultMutableTreeNode("Individual " + i);
+			treeIndiHashmap.put(child, population.get(i));
+			genNode.add(child);
+		}
+		treeRoot.insert(genNode, 0);
+		treeModel.reload();
+		
+	}
+}

+ 102 - 0
src/algorithms/geneticAlgorithm/holegGA/HolegCrossover.java

@@ -0,0 +1,102 @@
+package algorithms.geneticAlgorithm.holegGA;
+
+import java.util.ArrayList;
+
+import classes.AbstractCpsObject;
+import classes.CpsNode;
+import algorithms.geneticAlgorithm.Components.GACrossoverStrategy;
+
+public class HolegCrossover extends GACrossoverStrategy<HolegIndividual> {
+
+	@Override
+	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();
+		int splitIdx = (int) Math.ceil(parent1.holonObjects.size()/2);
+		
+		//HolonObjects
+		for(int i = 0; i < splitIdx; i++){
+			child.holonObjects.add(parent1.holonObjects.get(i).makeCopy());
+		}
+		int restAmount = parent1.holonObjects.size() - splitIdx;
+		for(int j = 0; j < restAmount; j++){
+			int idx = parent2.holonObjects.size() - 1; //greift auf letztes element zu
+			idx -= j;	//greift bei jedem durchlauf auf ein weiter vorderes element zu
+			if(idx >= 0){
+				child.holonObjects.add(parent2.holonObjects.get(idx).makeCopy());
+			}else{
+				break;
+			}
+		}
+		
+		//HolonEdges
+		splitIdx = (int)Math.ceil(parent1.holonEdges.size()/2);
+		for(int k = 0; k < splitIdx; k++){
+			int posA = parent1.holonEdges.get(k).aPos;
+			int posB = parent1.holonEdges.get(k).bPos;
+			AbstractCpsObject objA;
+			AbstractCpsObject objB;
+			
+			if(posA < child.holonObjects.size()){
+				objA = child.holonObjects.get(posA);
+				if(objA == null){
+					objA = new CpsNode("Node");
+					child.holonObjects.set(posA, objA);
+				}
+			}else{
+				objA = new CpsNode("Node");
+				child.holonObjects.add(objA);
+			}
+			
+			if(posB < child.holonObjects.size()){
+				objB = child.holonObjects.get(posB);
+				if(objB == null){
+					objB =  new CpsNode("Node");
+					child.holonObjects.set(posB, objB);
+				}
+			}else{
+				objB = new CpsNode("Node");
+				child.holonObjects.add(objB);
+			}
+			child.holonEdges.add(new GAEdge(posA, posB, objA, objB));
+		}
+		
+		restAmount = parent1.holonEdges.size() - splitIdx;
+		for(int l = 0; l < restAmount; l++){
+			int idx = parent2.holonEdges.size() - 1;
+			idx -= l;
+			
+			if(idx >= 0){
+				int posA = parent2.holonEdges.get(idx).aPos;
+				int posB = parent2.holonEdges.get(idx).bPos;
+				AbstractCpsObject objA;
+				AbstractCpsObject objB;
+			
+				if(posA < child.holonObjects.size()){
+					objA = child.holonObjects.get(posA);
+				}else{
+					objA = new CpsNode("Node");
+					child.holonObjects.add(objA); /// muss unbedingt geändert werden damit edges synchron sind
+				}
+			
+				if(posB < child.holonObjects.size()){
+					objB = child.holonObjects.get(posB);
+				}else{
+					objB = new CpsNode("Node");
+					child.holonObjects.add(objB);
+				}
+				child.holonEdges.add(new GAEdge(posA, posB, objA, objB));
+			}
+		}
+		return child;
+	}
+
+}

+ 81 - 0
src/algorithms/geneticAlgorithm/holegGA/HolegFactory.java

@@ -0,0 +1,81 @@
+package algorithms.geneticAlgorithm.holegGA;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Random;
+
+import classes.AbstractCpsObject;
+import classes.CpsNode;
+import classes.HolonBattery;
+import classes.HolonObject;
+import classes.HolonSwitch;
+import algorithms.geneticAlgorithm.Components.GAIndividualFactory;
+
+public class HolegFactory implements GAIndividualFactory<HolegIndividual> {
+
+	ArrayList<AbstractCpsObject> objectSpace;
+	int maxObjects;
+	int maxConnections;
+	Random rng;
+	
+	public HolegFactory(ArrayList<AbstractCpsObject> objects, int maxObjects, int maxConnections){
+		objectSpace = objects;
+		objectSpace.add(null);
+		this.maxObjects = maxObjects;
+		this.maxConnections = maxConnections;
+		rng = new Random();
+	}
+	
+	@Override
+	public HolegIndividual createRandomIndividual() {
+		HolegIndividual hI = new HolegIndividual();
+		createObjects(hI);
+		createEdges(hI);
+		return hI;
+	}
+	
+	public void createObjects(HolegIndividual hI){
+		
+		int objCount = rng.nextInt(maxObjects) + 1;
+		
+		for(int i = 0; i < objCount; i++){
+			
+			AbstractCpsObject absObj = objectSpace.get(rng.nextInt(objectSpace.size()));
+			AbstractCpsObject newObj = null;
+			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");
+			}
+			
+			hI.holonObjects.add(newObj);
+		}
+	}
+	
+	public void createEdges(HolegIndividual hI){
+		if(hI.holonObjects.size() > 1){
+			int edgeCount = rng.nextInt(maxConnections) + 1;
+			ArrayList<Integer> list = new ArrayList<Integer>();
+	    
+			for (int i = 0; i < hI.holonObjects.size(); i++) {
+				list.add(new Integer(i));
+			}
+	   
+		
+			for(int i = 0; i < edgeCount; i++){
+				Collections.shuffle(list);
+				int aPos = list.get(0);
+				int bPos = list.get(1);
+				hI.holonEdges.add(new GAEdge(aPos, bPos, hI.holonObjects.get(aPos), hI.holonObjects.get(bPos)));
+			}
+		}
+
+	}
+
+}

+ 38 - 0
src/algorithms/geneticAlgorithm/holegGA/HolegIndividual.java

@@ -0,0 +1,38 @@
+package algorithms.geneticAlgorithm.holegGA;
+
+import java.util.ArrayList;
+
+import classes.AbstractCpsObject;
+import algorithms.geneticAlgorithm.Components.GAIndividual;
+
+public class HolegIndividual extends GAIndividual {
+	
+	public ArrayList<AbstractCpsObject> holonObjects;
+	public ArrayList<GAEdge> holonEdges;
+	public ArrayList<HolegIndividual> parents;
+	public String id;
+	public int gen;
+	public int pos;
+	
+	public HolegIndividual(){
+		holonObjects = new  ArrayList<AbstractCpsObject>();
+		holonEdges = new ArrayList<GAEdge>();
+		parents = new ArrayList<HolegIndividual>();
+	}
+	
+	public ArrayList<HolegIndividual> getParents(){
+		return parents;
+	}
+	
+	public void setParents(ArrayList<HolegIndividual> parents){
+		this.parents = parents;
+	}
+	
+	public void setId(int Gen, int pos){
+		id = "Generation_" + Gen + " Position_" + pos;
+	}
+	
+	public String getId(){
+		return id;
+	}
+}

+ 3 - 0
src/classes/AbstractCpsObject.java

@@ -57,6 +57,7 @@ public abstract class AbstractCpsObject {
 		setImage("/Images/Dummy_House.png");
 		tags = new ArrayList<>();
 		pseudoTags = new ArrayList<>();
+		position = new Position(500, 500);
 	}
 
 	/**
@@ -353,5 +354,7 @@ public abstract class AbstractCpsObject {
 			}
 		}
 	}
+	
+	public abstract AbstractCpsObject makeCopy();
 
 }

+ 9 - 0
src/classes/CpsNode.java

@@ -24,4 +24,13 @@ public class CpsNode extends AbstractCpsObject {
 		this.setSav("CVS");
 		this.setId(IdCounter.nextId());
 	}
+	
+	public CpsNode(CpsNode node){
+		super(node);
+	}
+
+	@Override
+	public AbstractCpsObject makeCopy() {
+		return new CpsNode(this);
+	}
 }

+ 10 - 0
src/classes/CpsUpperNode.java

@@ -35,6 +35,7 @@ public class CpsUpperNode extends AbstractCpsObject {
 		this.setNodesIdx(new HashMap<>());
 	}
 
+
 	/**
 	 * @return the nodes
 	 */
@@ -204,4 +205,13 @@ public class CpsUpperNode extends AbstractCpsObject {
 	public void setLeftBorder(int leftBorder) {
 		this.leftBorder = leftBorder;
 	}
+	
+	/*
+	 * Does not make a real copy
+	 * (non-Javadoc)
+	 * @see classes.AbstractCpsObject#makeCopy()
+	 */
+	public CpsUpperNode makeCopy(){
+		return this;
+	}
 }

+ 4 - 0
src/classes/HolonBattery.java

@@ -191,4 +191,8 @@ public class HolonBattery extends AbstractCpsObject{
 			return stateOfChargeToValid;
 		}
 	}
+	
+	public HolonBattery makeCopy(){
+		return new HolonBattery(this);
+	}
 }

+ 4 - 0
src/classes/HolonObject.java

@@ -584,4 +584,8 @@ public class HolonObject extends AbstractCpsObject {
 	public float getSuppliedPercentage(){
 		return suppliedPercentage;
 	}
+	
+	public HolonObject makeCopy(){
+		return new HolonObject(this);
+	}
 }

+ 4 - 0
src/classes/HolonSwitch.java

@@ -280,4 +280,8 @@ public class HolonSwitch extends AbstractCpsObject implements IGraphedElement {
 	public void setStretching(boolean stretch) {
 		this.stretch=stretch;
 	}
+	
+	public HolonSwitch makeCopy(){
+		return new HolonSwitch(this);
+	}
 }

+ 4 - 0
src/classes/HolonTransformer.java

@@ -87,4 +87,8 @@ public class HolonTransformer extends AbstractCpsObject {
 		return output;
 
 	}
+	
+	public HolonTransformer makeCopy(){
+		return new HolonTransformer(this);
+	}
 }

+ 2 - 0
src/ui/view/AddObjectPopUp.java

@@ -163,6 +163,8 @@ public class AddObjectPopUp extends JDialog {
 						new ImageIcon(filePath).getImage().getScaledInstance(50, 50, Image.SCALE_SMOOTH));
 						*/
 				lblImagePreview.setIcon(new ImageIcon(Util.loadImage(this, obj.getImage(), 50, 50)));
+				sourcePath.setText(obj.getImage());
+				filePath = obj.getImage();
 			}
 			sourcePath.setBounds(148, 77, 271, 20);
 			contentPanel.add(sourcePath);

+ 16 - 0
src/ui/view/AlgorithmMenu.java

@@ -1,5 +1,7 @@
 package ui.view;
 
+import algorithms.geneticAlgorithm.holegGA.GenAlgoInit;
+import algorithms.geneticAlgorithm.holegGA.GenAlgoWindow;
 import api.CpsAlgorithm;
 import ui.controller.Control;
 import ui.model.Model;
@@ -7,6 +9,7 @@ import ui.model.Model;
 import javax.swing.*;
 import javax.tools.JavaCompiler;
 import javax.tools.ToolProvider;
+
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -26,6 +29,8 @@ public class AlgorithmMenu extends JMenu {
 
 	private static final long serialVersionUID = 1L;
 
+	GenAlgoWindow genAlgoWindow;
+	JMenuItem geneticAlgoBtn = new JMenuItem("Build Network");
 	JMenuItem algoFolderButton = new JMenuItem("Select Algorithm Folder");
 	// root Directory
 	File root = null;
@@ -104,8 +109,19 @@ public class AlgorithmMenu extends JMenu {
 			}
 
 		});
+		
+		geneticAlgoBtn.addActionListener(new ActionListener(){
+
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				GenAlgoInit algoInit = new GenAlgoInit(controller, model);
+				algoInit.start();
+			}
+			
+		});
 
 		// Add to Panel
+		this.add(geneticAlgoBtn);
 		this.add(algoFolderButton);
 		this.add(mnSelectAlgorithm);
 		mnSelectAlgorithm.add(noneItem);

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

@@ -312,7 +312,6 @@ public class GUI implements CategoryListener {
 		this.unitGraph = new UnitGraph(model, control);
 		this.canvas = new MyCanvas(model, control, unitGraph);
 		this.holonCanvas = new HolonCanvas(model, control);
-
 		control.initListener(this);
 		controller.setCanvas(canvas);
 		model.setConsole(console);