Browse Source

Fixes Algorithms

Adds Edit/Add Object to CanvasPanel
TomTroppmann 2 years ago
parent
commit
50788d2b8f
27 changed files with 660 additions and 792 deletions
  1. 14 20
      src/holeg/addon/Randomizer.java
  2. 1 1
      src/holeg/algorithm/binary/PsoAlgorithm.java
  3. 27 30
      src/holeg/algorithm/objective_function/Evaluation.java
  4. 68 92
      src/holeg/algorithm/objective_function/GraphMetrics.java
  5. 78 120
      src/holeg/algorithm/objective_function/ObjectiveFunctionByCarlos.java
  6. 19 24
      src/holeg/algorithm/objective_function/SwitchObjectiveFunction.java
  7. 118 134
      src/holeg/algorithm/objective_function/TopologieObjectiveFunction.java
  8. 2 2
      src/holeg/api/AlgorithmFrameworkFlex.java
  9. 2 2
      src/holeg/api/TopologieAlgorithmFramework.java
  10. 0 2
      src/holeg/model/AbstractCanvasObject.java
  11. 3 20
      src/holeg/model/Constrain.java
  12. 119 5
      src/holeg/model/Holon.java
  13. 17 14
      src/holeg/model/HolonObject.java
  14. 3 0
      src/holeg/preferences/PreferenceKeys.java
  15. 63 0
      src/holeg/serialize/CategoryAdapter.java
  16. 0 1
      src/holeg/serialize/ModelDeserializer.java
  17. 29 14
      src/holeg/ui/controller/Control.java
  18. 1 0
      src/holeg/ui/view/Main.java
  19. 24 28
      src/holeg/ui/view/category/CategoryPanel.java
  20. 2 14
      src/holeg/ui/view/dialog/AddElementPopUp.java
  21. 8 10
      src/holeg/ui/view/dialog/AddObjectPopUp.java
  22. 0 251
      src/holeg/ui/view/dialog/CreateNewDialog.java
  23. 0 2
      src/holeg/ui/view/dialog/CreateTemplatePopUp.java
  24. 58 0
      src/holeg/ui/view/dialog/NewCategoryDialog.java
  25. 0 3
      src/holeg/ui/view/image/Import.java
  26. 3 3
      src/holeg/ui/view/inspector/UnitGraph.java
  27. 1 0
      src/holeg/ui/view/main/Gui.java

+ 14 - 20
src/holeg/addon/Randomizer.java

@@ -50,12 +50,12 @@ public class Randomizer implements AddOn {
 	private Control  control;
 	private int minAmountOfElements = 3;
 	private int maxAmountOfElements = 7;
-	private JPanel content = new JPanel();
-	private JPanel tablePanel = new JPanel();
-	private RandomPriotity prioPanel = new RandomPriotity();
-	private JCheckBox priorityCheckbox = new JCheckBox("Random");
+	private final JPanel content = new JPanel();
+	private final JPanel tablePanel = new JPanel();
+	private final RandomPriotity prioPanel = new RandomPriotity();
+	private final JCheckBox priorityCheckbox = new JCheckBox("Random");
 	private boolean useRandomPriority = true;
-	
+
 	//To Test the Layout Faster   
 	public static void main(String[] args)
     {
@@ -141,9 +141,7 @@ public class Randomizer implements AddOn {
 			entryPanel.add(Box.createHorizontalGlue());
 			JCheckBox checkbox = new JCheckBox();
 			checkbox.setSelected(true);
-			checkbox.addItemListener(change -> {
-				objectMap.put(hObject, checkbox.isSelected());
-			});
+			checkbox.addItemListener(change -> objectMap.put(hObject, checkbox.isSelected()));
 			checkboxList.add(checkbox);
 			entryPanel.add(checkbox);
 			tablePanel.add(entryPanel);
@@ -216,11 +214,11 @@ public class Randomizer implements AddOn {
 	}
 	
 	private void run() {
-		List<HolonElementSketch> holonElementCatalog = new ArrayList<HolonElementSketch>();
+		List<HolonElementSketch> holonElementCatalog = new ArrayList<>();
 		if(file == null)file = openCatalogFile();
 		if(file == null) return;
 		readCatalogFromJson(file, holonElementCatalog);
-		holonElementCatalog.forEach(con -> con.checkValues());
+		holonElementCatalog.forEach(HolonElementSketch::checkValues);
 		objectMap.forEach((hObject, state) ->{
 			//Ignore Filtered objects 
 			System.out.println("hObject:" + hObject + " state:" + state);
@@ -268,10 +266,10 @@ public class Randomizer implements AddOn {
 		flipChance.setMajorTickSpacing(50);
 		flipChance.setMinorTickSpacing(5);
 		flipChance.setPaintTicks(true);
-		Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
-		labelTable.put( Integer.valueOf(0), new JLabel("0.0") );
-		labelTable.put( Integer.valueOf(50), new JLabel("0.5") );
-		labelTable.put( Integer.valueOf(100), new JLabel("1.0") );
+		Hashtable<Integer, JLabel> labelTable = new Hashtable<>();
+		labelTable.put(0, new JLabel("0.0") );
+		labelTable.put(50, new JLabel("0.5") );
+		labelTable.put(100, new JLabel("1.0") );
 		flipChance.setToolTipText("" +randomChance);
 		flipChance.addChangeListener(actionEvent ->{
 			randomChance  =(double)flipChance.getValue()/100.0;
@@ -296,14 +294,10 @@ public class Randomizer implements AddOn {
 					catalog.add(newObject);
 				});
 			}	
-		} catch (JsonSyntaxException e) {
-			e.printStackTrace();
-		} catch (JsonIOException e) {
-			e.printStackTrace();
-		} catch (FileNotFoundException e) {
+		} catch (JsonSyntaxException | JsonIOException | FileNotFoundException e) {
 			e.printStackTrace();
 		}
-		
+
 	}
 	
 	

+ 1 - 1
src/holeg/algorithm/binary/PsoAlgorithm.java

@@ -86,7 +86,7 @@ public class PsoAlgorithm extends AlgorithmFrameworkFlex{
 	 *  w inertia, calculated from phi(Variable:{@link #dependency})<br>
 	 *  c1:	influence, calculated from phi(Variable:{@link #dependency}) <br>
 	 *  c2:	influence, calculated from phi(Variable:{@link #dependency})<br>
-	 *  r<sub>mu</sub>: probability that the proposed operation is conducted defined by limit(Variable:{@link #limit})<br>
+	 *  r<sub>mu</sub>: probability that the proposed operation is conducted defined by limit(Variable:{@link #})<br>
 	 *  
 	 *  
 	 */

+ 27 - 30
src/holeg/algorithm/objective_function/Evaluation.java

@@ -1,11 +1,14 @@
 package holeg.algorithm.objective_function;
 
+import holeg.model.Flexibility;
+import holeg.model.Holon;
 import holeg.model.HolonObject;
 import holeg.model.HolonObject.HolonObjectState;
 import holeg.model.HolonElement.Priority;
 import holeg.model.Model;
 
-//TODO(Tom2022-01-13) Fix Evaluation
+import java.util.List;
+
 public class Evaluation {
 	
 	/**
@@ -18,35 +21,29 @@ public class Evaluation {
 		double object_fitness = 0.0;
 		double flexFitness = 0.0;
 		
-//		double sigma = 9;
-//		
-//		// calculate network_fitness
-//		for(DecoratedNetwork net : state.getNetworkList()) {
-//			float production = net.getSupplierList().stream().map(supplier -> supplier.getEnergyToSupplyNetwork()).reduce(0.0f, (a, b) -> a + b);
-//			float consumption = net.getConsumerList().stream().map(con -> con.getEnergyNeededFromNetwork()).reduce(0.0f, (a, b) -> a + b);
-//			nw_fitness += Math.abs((production - consumption)/100); //Energy is now everywhere positive
-//		}
-//		
-//		// calculate object_fitness
-//		for(DecoratedNetwork net : state.getNetworkList()) {
-//
-//			object_fitness += net.getConsumerList().stream().map(con -> holonObjectSupplyPenaltyFunction(con.getSupplyBarPercentage()) /*+ inactiveHolonElementPenalty(con.getModel())*/).reduce(0.0, (a, b) -> (a + b));
-//			object_fitness += net.getConsumerList().stream().map(con -> StateToDouble(con.getState())).reduce(0.0, (a,b) -> (a+b));
-//			//object_fitness += net.getPassivNoEnergyList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b));
-//			//object_fitness += net.getSupplierList().stream().map(sup -> inactiveHolonElementPenalty(sup.getModel())).reduce(0.0, (a, b) -> (a + b));
-//			//object_fitness += net.getConsumerSelfSuppliedList().stream().map(con -> inactiveHolonElementPenalty(con.getModel())).reduce(0.0, (a, b) -> (a + b));
-//
-//		}
-//		// calculate flexibility fitness old cost flex
-//		/*for(FlexWrapper flexWrapper :state.getFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)) {
-//			flexFitness += flexWrapper.cost / (double)flexWrapper.getDuration();
-//		}*/
-//		List<Flexibility> getAllFlexInUse = state.getAllFlex().filter(flex -> flex.getState().equals(FlexState.IN_USE)).toList();
-//		for(Flexibility flex : getAllFlexInUse) {
-//			flexFitness += Math.pow(sigma, (double)priorityToInt(flex.getElement().getPriority())) - 1;
-//		}
-//		
-//		fitness = nw_fitness + object_fitness + flexFitness;
+		double sigma = 9;
+
+		// calculate network_fitness
+		for(Holon holon : model.holons) {
+			float production = holon.getTotalProduction();
+			float consumption = holon.getTotalConsumption();
+			nw_fitness += Math.abs((production - consumption)/100); //Energy is now everywhere positive
+		}
+
+
+
+		// calculate object_fitness
+		for(Holon holon : model.holons) {
+
+			object_fitness += holon.holonObjects.stream().filter(HolonObject::isConsumer).map(con -> holonObjectSupplyPenaltyFunction(con.getSupplyBarPercentage()) /*+ inactiveHolonElementPenalty(con.getModel())*/).reduce(0.0, Double::sum);
+			object_fitness += holon.holonObjects.stream().filter(HolonObject::isConsumer).map(con -> StateToDouble(con.getState())).reduce(0.0, Double::sum);
+		}
+		List<Flexibility> getAllFlexInUse = model.getAllFlexibilities().stream().filter(flex -> flex.getState().equals(Flexibility.FlexState.IN_USE)).toList();
+		for(Flexibility flex : getAllFlexInUse) {
+			flexFitness += Math.pow(sigma, (double)priorityToInt(flex.getElement().getPriority())) - 1;
+		}
+
+		fitness = nw_fitness + object_fitness + flexFitness;
 		return fitness;
 	}
 

+ 68 - 92
src/holeg/algorithm/objective_function/GraphMetrics.java

@@ -1,17 +1,9 @@
 package holeg.algorithm.objective_function;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
 import java.util.logging.Logger;
 
-import holeg.model.AbstractCanvasObject;
-import holeg.model.Model;
-
-import java.util.Set;
+import holeg.model.*;
 
 //TODO(Tom2022-01-13) Fix GraphMetrics
 public class GraphMetrics {
@@ -56,94 +48,78 @@ public class GraphMetrics {
 	 * Convert a DecoratedNetwork to a Graph
 	 * @return a equivalent Graph to the DecoratedNetwork
 	 */
-	public static Graph convertDecoratedNetworkToGraph(Model model) {
+	public static Graph convertDecoratedNetworkToGraph(Model model, Holon holon) {
 		Graph G = new Graph();
 		HashMap<AbstractCanvasObject, Integer> objectToId = new HashMap<>();
 		List<Integer> sourcesList = new ArrayList<Integer>();
 		int count = 0;
-//		for(Consumer con: net.getConsumerList()) {
-//			objectToId.put(con.getModel(), count);
-//			sourcesList.add(count);
-//			count++;
-//		}
-//		for(Consumer con: net.getConsumerSelfSuppliedList()) {
-//			objectToId.put(con.getModel(), count);
-//			sourcesList.add(count);
-//			count++;
-//		}
-//		for(Passiv pas: net.getPassivNoEnergyList()) {
-//			objectToId.put(pas.getModel(), count);
-//			sourcesList.add(count);
-//			count++;
-//		}
-//		for(Supplier sup: net.getSupplierList()) {
-//			objectToId.put(sup.getModel(), count);
-//			sourcesList.add(count);
-//			count++;
-//		}
-//		
-		
+
+		for(HolonObject con: holon.holonObjects) {
+			objectToId.put(con, count);
+			sourcesList.add(count);
+			count++;
+		}
 		
 		//Generate EdgeList 
-//		List<Edge> edgeList = new ArrayList<Edge>();
-//		for(holeg.model.Edge cable : net.getDecoratedCableList()){
-//			
-//			AbstractCanvasObject objectA = cable.getA();
-//			AbstractCanvasObject objectB = cable.getB();
-//			if(objectA == null) {
-//				log.warning("Edge: " + cable + "objectA == null");
-//				continue;
-//			}
-//			if(objectB == null) {
-//				log.warning("Edge: " + cable + "objectB == null");
-//				continue;
-//			}
-//			
-//			//SpecialCase for open switches
-//			if(objectA instanceof HolonSwitch sw && !sw.getManualState()) {
-//				continue;
-//			}
-//			if(objectB instanceof HolonSwitch sw && !sw.getManualState()) {
-//				continue;
-//			}
-//			
-//			int idA = -1;
-//			if(objectToId.containsKey(objectA)) {
-//				idA = objectToId.get(objectA);
-//			}else {
-//				idA = count;
-//				objectToId.put(objectA, count++);
-//			}
-//			int idB = -1;
-//			if(objectToId.containsKey(objectB)) {
-//				idB = objectToId.get(objectB);
-//			}else {
-//				idB = count;
-//				objectToId.put(objectB, count++);
-//			}
-//			double length = cable.getLength();
-//			edgeList.add(new Edge(idA, idB, length));
-//		}
-//		//Generate EdgeArray
-//		G.E = new Edge[edgeList.size()];
-//		for(int i=0;i<edgeList.size();i++)
-//	    {
-//				G.E[i] =  edgeList.get(i);
-//	    }
-//		//Generate VertexArray
-//		G.V = new Vertex[objectToId.size()];
-//		int entryCount = 0;
-//		for(Entry<AbstractCanvasObject, Integer> entry : objectToId.entrySet()) {
-//			G.V[entryCount] =  new Vertex(entry.getValue());
-//			entryCount++;
-//		}
-//		//Generate Sources Array
-//		int sourceCount = 0;
-//		G.S = new Vertex[sourcesList.size()];
-//		for(int source : sourcesList) {
-//			G.S[sourceCount] = new Vertex(source);
-//			sourceCount++;
-//		}
+		List<Edge> edgeList = new ArrayList<Edge>();
+		for(holeg.model.Edge cable : model.getEdgesOnCanvas()){
+
+			AbstractCanvasObject objectA = cable.getA();
+			AbstractCanvasObject objectB = cable.getB();
+			if(objectA == null) {
+				log.warning("Edge: " + cable + "objectA == null");
+				continue;
+			}
+			if(objectB == null) {
+				log.warning("Edge: " + cable + "objectB == null");
+				continue;
+			}
+
+			//SpecialCase for open switches
+			if(objectA instanceof HolonSwitch sw && !sw.getState().isOpen()) {
+				continue;
+			}
+			if(objectB instanceof HolonSwitch sw && !sw.getState().isOpen()) {
+				continue;
+			}
+
+			int idA = -1;
+			if(objectToId.containsKey(objectA)) {
+				idA = objectToId.get(objectA);
+			}else {
+				idA = count;
+				objectToId.put(objectA, count++);
+			}
+			int idB = -1;
+			if(objectToId.containsKey(objectB)) {
+				idB = objectToId.get(objectB);
+			}else {
+				idB = count;
+				objectToId.put(objectB, count++);
+			}
+			double length = cable.getLength();
+			edgeList.add(new Edge(idA, idB, length));
+		}
+		//Generate EdgeArray
+		G.E = new Edge[edgeList.size()];
+		for(int i=0;i<edgeList.size();i++)
+	    {
+				G.E[i] =  edgeList.get(i);
+	    }
+		//Generate VertexArray
+		G.V = new Vertex[objectToId.size()];
+		int entryCount = 0;
+		for(Map.Entry<AbstractCanvasObject, Integer> entry : objectToId.entrySet()) {
+			G.V[entryCount] =  new Vertex(entry.getValue());
+			entryCount++;
+		}
+		//Generate Sources Array
+		int sourceCount = 0;
+		G.S = new Vertex[sourcesList.size()];
+		for(int source : sourcesList) {
+			G.S[sourceCount] = new Vertex(source);
+			sourceCount++;
+		}
 		return G;
 	}
 	

+ 78 - 120
src/holeg/algorithm/objective_function/ObjectiveFunctionByCarlos.java

@@ -2,27 +2,18 @@ package holeg.algorithm.objective_function;
 
 import java.util.logging.Logger;
 
+import holeg.model.Flexibility;
+import holeg.model.Holon;
 import holeg.model.HolonElement.Priority;
+import holeg.model.HolonObject;
 import holeg.model.Model;
 
 public class ObjectiveFunctionByCarlos {
 	// Parameters
 	private static final Logger log = Logger.getLogger(ObjectiveFunctionByCarlos.class.getName());
-	// weight for f_g(H)
 	static double w_eb = .3, w_state = .3, w_pro = .2, w_perf = .1, w_holon = .1;
-	// killswitch weights
-	// static double w_eb = 0.5, w_state = 0.5, w_pro = 0.0f, w_perf = .0,
-	// w_holon=.0;
-
-	// kappas for squashing function
-//	
-	// static double k_eb = 1050000.f, k_state = 10000, k_pro = 2000, k_perf =
-	// 11000, k_holon= 150000;
-//  oversupplied
-	static double k_eb = 750000.f, k_state = 20000, k_pro = 3000, k_perf = 15000, k_holon = 200000;
 
-//	old values undersupplied 
-//	static double k_eb = 1000000.f, k_state = 15000, k_pro = 2100, k_perf = 12000, k_holon= 200000;
+	static double k_eb = 750000.f, k_state = 20000, k_pro = 3000, k_perf = 15000, k_holon = 200000;
 
 	// theta for f_pro
 	static double theta = 3;
@@ -76,87 +67,75 @@ public class ObjectiveFunctionByCarlos {
 	 *
 	 * @return f_g value between 0 and 100
 	 */
-	//TODO(Tom2022-01-13) Fix ObjectiveFunctionByCarlos
 	static public double getFitnessValueForState(Model model) {
 
-//		// Calculate f_eb the penalty for unbalenced energy in the network
-//		double f_eb = 0;
-//		// sum over all objects
-//		for (DecoratedNetwork net : state.getNetworkList()) {
-//			double netEnergyDifference = 0;
-//			netEnergyDifference += net.getConsumerList().stream()
-//					.map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets())
-//					.reduce(0.f, Float::sum);
-//			netEnergyDifference += net.getConsumerSelfSuppliedList().stream()
-//					.map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets())
-//					.reduce(0.f, Float::sum);
-//			netEnergyDifference += net.getSupplierList().stream()
-//					.map(sup -> sup.getEnergyProducing() - sup.getEnergySelfConsuming()).reduce(0.f, Float::sum);
-//			// abs
-//			f_eb += Math.abs(netEnergyDifference);
-//		}
-//
-//		// Calculate f_state the penalty function for the supply state
-//		double f_state = 0;
-//		for (DecoratedNetwork net : state.getNetworkList()) {
-//			f_state += net.getConsumerList().stream().map(con -> supplyPenalty(con.getSupplyBarPercentage())).reduce(0.,
-//					Double::sum);
-//		}
-//
-//		// calculate f_pro the penalty function for priority usage
-//		// for each active flexibility punish
-//
-//		List<Flexibility> allFlexOrdered = state.getAllFlex().filter(flex -> flex.getState().equals(FlexState.IN_USE))
-//				.toList();
-//		double f_pro = 0;
-//		f_pro = allFlexOrdered.stream()
-//				.map(flex -> Math.pow(theta, priorityToDouble(flex.getElement().getPriority())) - 1.0)
-//				.reduce(0.0, Double::sum);
-//
-//		// calculate f_perf the penalty function for the quality of a flexibility used
-//
-//		// and the subfuction f_unre, f_cool, f_dur
-//		double f_perf = 0;
-//		for (Flexibility flex : allFlexOrdered) {
-//			double f_unre = unresponsivnessPenalty(flex.getSpeed());
-//			double f_cool = cooldownPenalty(flex.getCooldown());
-//			double f_dur = durationPenalty(flex.getDuration());
-//			f_perf += f_unre + f_cool + f_dur;
-//		}
-//
-//		// calculate f_holon
-//		double f_holon = 0;
-//		for (DecoratedNetwork net : state.getNetworkList()) {
-//			double f_elements_diviation_production = net.getDeviationInProductionInNetworkForHolonObjects();
-//			double f_elements_diviation_consumption = net.getDeviationInProductionInNetworkForHolonObjects();
-//			double f_flexibility_diviation_consumption = net.getDiviationInFlexibilityConsumption();
-//			double f_flexibility_diviation_production = net.getDiviationInFlexibilityProduction();
-//
-//			double con = net.getTotalConsumption();
-//			double prod = net.getTotalProduction();
-//			double flexcapProd = net.getFlexibilityProductionCapacity();
-//			double flexcapCon = net.getFlexibilityConsumptionCapacity();
-//			double f_change_positive = lambda_f_change
-//					- lambda_f_change * Math.min(1, (con > 0.0) ? flexcapProd / con : 1.0);
-//			double f_change_negativ = lambda_f_change
-//					- lambda_f_change * Math.min(1, (prod > 0.0) ? flexcapCon / prod : 1.0);
-//
-//			double f_element = f_elements_diviation_production + f_elements_diviation_consumption;
-//			double f_flexibility = f_flexibility_diviation_consumption + f_flexibility_diviation_production;
-//			double f_change = f_change_positive + f_change_negativ;
-//
-//			f_holon += f_element + f_flexibility + f_change;
-//		}
-//		double q1 = squash(f_eb, k_eb);
-//		double q2 = squash(f_state, k_state);
-//		double q3 = squash(f_pro, k_pro);
-//		double q4 = squash(f_perf, k_perf);
-//		double q5 = squash(f_holon, k_holon);
-//		log.finer("f_eb= " + f_eb + " f_state= " + f_state + " f_pro= " + f_pro + " f_perf= " + f_perf + " f_holon= "
-//				+ f_holon + " q1= " + q1 + " q2= " + q2 + " q3= " + q3 + " q4= " + q4 + " q5= " + q5);
-//
-//		return w_eb * q1 + w_state * q2 + w_pro * q3 + w_perf * q4 + w_holon * q5;
-		return 0;
+		// Calculate f_eb the penalty for unbalenced energy in the network
+		double f_eb = 0;
+		// sum over all objects
+		for (Holon holon : model.holons) {
+			double netEnergyDifference = holon.holonObjects.stream().map(hO -> Math.abs(hO.getActualEnergy())).reduce(0.0f, Float::sum);
+			f_eb += netEnergyDifference;
+		}
+
+		// Calculate f_state the penalty function for the supply state
+		double f_state = 0;
+		for (Holon holon : model.holons) {
+			f_state += holon.holonObjects.stream().filter(hO -> hO.getState() != HolonObject.HolonObjectState.PRODUCER)
+					.map(HolonObject::getSupplyBarPercentage).reduce(0.f, Float::sum);
+		}
+
+		// calculate f_pro the penalty function for priority usage
+		// for each active flexibility punish
+
+		double f_pro = model.getAllFlexibilities().stream().filter(flex -> flex.getState().equals(Flexibility.FlexState.IN_USE))
+				.map(flex -> Math.pow(theta, priorityToDouble(flex.getElement().getPriority())) - 1.0)
+				.reduce(0.0, Double::sum);
+
+
+		// calculate f_perf the penalty function for the quality of a flexibility used
+
+
+		// and the subfuction f_unre, f_cool, f_dur
+		double f_perf = 0;
+		for (Flexibility flex : model.getAllFlexibilities().stream().filter(flex -> flex.getState().equals(Flexibility.FlexState.IN_USE)).toList()) {
+			double f_unre = unresponsivnessPenalty(flex.getSpeed());
+			double f_cool = cooldownPenalty(flex.getCooldown());
+			double f_dur = durationPenalty(flex.getDuration());
+			f_perf += f_unre + f_cool + f_dur;
+		}
+
+		// calculate f_holon
+		double f_holon = 0;
+		for (Holon net : model.holons) {
+			double f_elements_deviation_production = net.getDeviationInProductionInNetworkForHolonObjects();
+			double f_elements_deviation_consumption = net.getDeviationInProductionInNetworkForHolonObjects();
+			double f_flexibility_deviation_consumption = net.getDiviationInFlexibilityConsumption();
+			double f_flexibility_deviation_production = net.getDiviationInFlexibilityProduction();
+
+			double con = net.getTotalConsumption();
+			double prod = net.getTotalProduction();
+			double flexcapProd = net.getFlexibilityProductionCapacity();
+			double flexcapCon = net.getFlexibilityConsumptionCapacity();
+			double f_change_positive = lambda_f_change
+					- lambda_f_change * Math.min(1, (con > 0.0) ? flexcapProd / con : 1.0);
+			double f_change_negativ = lambda_f_change
+					- lambda_f_change * Math.min(1, (prod > 0.0) ? flexcapCon / prod : 1.0);
+
+			double f_element = f_elements_deviation_production + f_elements_deviation_consumption;
+			double f_flexibility = f_flexibility_deviation_consumption + f_flexibility_deviation_production;
+			double f_change = f_change_positive + f_change_negativ;
+
+			f_holon += f_element + f_flexibility + f_change;
+		}
+		double q1 = squash(f_eb, k_eb);
+		double q2 = squash(f_state, k_state);
+		double q3 = squash(f_pro, k_pro);
+		double q4 = squash(f_perf, k_perf);
+		double q5 = squash(f_holon, k_holon);
+		log.finer("f_eb= " + f_eb + " f_state= " + f_state + " f_pro= " + f_pro + " f_perf= " + f_perf + " f_holon= "
+				+ f_holon + " q1= " + q1 + " q2= " + q2 + " q3= " + q3 + " q4= " + q4 + " q5= " + q5);
+
+		return w_eb * q1 + w_state * q2 + w_pro * q3 + w_perf * q4 + w_holon * q5;
 	}
 
 	/**
@@ -164,7 +143,6 @@ public class ObjectiveFunctionByCarlos {
 	 * 
 	 * @param x     the input
 	 * @param kappa the corresponding kappa
-	 * @return
 	 */
 	static public double squash(double x, double kappa) {
 		return 100.f / (1.0f + Math.exp(-(10.f * (x - kappa / 2.f)) / kappa)) - squash_subtract;
@@ -174,7 +152,6 @@ public class ObjectiveFunctionByCarlos {
 	 * f_sup in paper
 	 * 
 	 * @param supply from 0 to 1
-	 * @return
 	 */
 	static public double supplyPenalty(double supply) {
 		double supplyPercentage = 100 * supply;
@@ -183,31 +160,17 @@ public class ObjectiveFunctionByCarlos {
 		return (supplyPercentage < 100) ? -0.5 * supplyPercentage + 50 : supplyPercentage - 100;
 	}
 
-	/**
-	 * prio function in the paper
-	 * 
-	 * @param priority
-	 * @return
-	 */
 	private static double priorityToDouble(Priority priority) {
-		switch (priority) {
-		case Essential:
-			return 3.;
-		case High:
-			return 2.;
-		case Medium:
-			return 1.;
-		case Low:
-		default:
-			return 0.;
-		}
+		return switch (priority) {
+			case Essential -> 3.;
+			case High -> 2.;
+			case Medium -> 1.;
+			default -> 0.;
+		};
 	}
 
 	/**
 	 * Attention Math.log calcultae ln not log
-	 * 
-	 * @param kappa
-	 * @return
 	 */
 	private static double range(double kappa) {
 		return -kappa / Math.log(Math.pow(2.0, 0.05) - 1.0);
@@ -215,9 +178,7 @@ public class ObjectiveFunctionByCarlos {
 
 	/**
 	 * f_unre
-	 * 
-	 * @param unresponsiv
-	 * @return
+
 	 */
 	private static double unresponsivnessPenalty(double unresponsiv) {
 		return (2.0 * lambda_f_unre) / (1 + Math.exp(-unresponsiv / range_for_kappa_f_unre)) - lambda_f_unre;
@@ -225,9 +186,6 @@ public class ObjectiveFunctionByCarlos {
 
 	/**
 	 * f_cool
-	 * 
-	 * @param cooldown
-	 * @return
 	 */
 	private static double cooldownPenalty(double cooldown) {
 		return (2.0 * lambda_f_cool) / (1 + Math.exp(-cooldown / range_for_kappa_f_cool)) - lambda_f_cool;

+ 19 - 24
src/holeg/algorithm/objective_function/SwitchObjectiveFunction.java

@@ -1,5 +1,7 @@
 package holeg.algorithm.objective_function;
 
+import holeg.model.Holon;
+import holeg.model.HolonObject;
 import holeg.model.Model;
 
 public class SwitchObjectiveFunction {
@@ -9,31 +11,26 @@ public class SwitchObjectiveFunction {
 	static double k_eb = 1050000.f, k_state = 10000;
 	
 	static double squash_subtract = 1.0f / (1.f + (float) Math.exp(5.0));
-	
-	
-	//TODO(Tom2022-01-13) Fix SwitchObjectiveFunction
+
 	static public float getFitnessValueForState(Model model) {
 		double f_eb = 0;
 		double f_state = 0;
-//		double elementCountInNetwork = state.getNetworkList().stream().map(net -> net.getAmountOfElements()).reduce(0, Integer::sum);
-//		//sum over all objects
-//		for(DecoratedNetwork net : state.getNetworkList()) {
-//			
-//			//weigt
-//			double w_network = net.getAmountOfElements()/elementCountInNetwork;
-//			
-//			//f_eb
-//			double netEnergyDifference = 0;
-//			netEnergyDifference += net.getConsumerList().stream().map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets()).reduce(0.f, Float::sum);
-//			netEnergyDifference += net.getConsumerSelfSuppliedList().stream().map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets()).reduce(0.f, Float::sum);
-//			netEnergyDifference += net.getSupplierList().stream().map(sup -> sup.getEnergyProducing() - sup.getEnergySelfConsuming()).reduce(0.f, Float::sum);
-//			//abs
-//			f_eb += w_network * Math.abs(netEnergyDifference);
-//			
-//			
-//			//f_state
-//			f_state += w_network * net.getConsumerList().stream().map(con -> supplyPenalty(con.getSupplyBarPercentage())).reduce(0., Double::sum);
-//		}
+		double elementCountInNetwork = model.getAllHolonElements().size();
+		//sum over all objects
+		for(Holon holon : model.holons) {
+
+			//weigt
+			double w_network = holon.getAmountOfElements()/elementCountInNetwork;
+
+			//f_eb
+			double netEnergyDifference = holon.holonObjects.stream().map(hO -> Math.abs(hO.getActualEnergy())).reduce(0.0f, Float::sum);
+			//abs
+			f_eb += w_network * Math.abs(netEnergyDifference);
+
+
+			//f_state
+			f_state += w_network * holon.holonObjects.stream().filter(HolonObject::isConsumer).map(con -> supplyPenalty(con.getSupplyBarPercentage())).reduce(0., Double::sum);
+		}
 		return (float) (w_eb*squash(f_eb, k_eb) + w_state*squash(f_state, k_state));
 	}
 	
@@ -41,7 +38,6 @@ public class SwitchObjectiveFunction {
 	/**
 	 * f_sup in paper
 	 * @param supply from 0 to 1
-	 * @return
 	 */
 	static public double supplyPenalty(double supply) {
 		double supplyPercentage = 100 * supply;
@@ -52,7 +48,6 @@ public class SwitchObjectiveFunction {
 	 * The squashing function in paper
 	 * @param x the input
 	 * @param kappa the corresponding kappa
-	 * @return
 	 */
 	static public double squash(double x, double kappa) {
 		return 100.f/(1.0f + Math.exp(-(10.f * (x - kappa/2.f))/ kappa)) - squash_subtract;

+ 118 - 134
src/holeg/algorithm/objective_function/TopologieObjectiveFunction.java

@@ -4,6 +4,8 @@ package holeg.algorithm.objective_function;
 import java.util.Locale;
 import java.util.logging.Logger;
 
+import holeg.model.Holon;
+import holeg.model.HolonObject;
 import holeg.model.Model;
 import holeg.utility.math.decimal.Sampler;
 
@@ -98,141 +100,123 @@ public class TopologieObjectiveFunction {
 	 */
 	//TODO(Tom2022-01-13) Fix TopologyFitnessFunction
 	static public float getFitnessValueForState(Model model, int amountOfAddedSwitch, double addedCableMeters, boolean moreInformation) {
-//		
-//		
-//
-//		//Calculate f_eb the penalty for unbalenced energy in the network
-//		double f_eb = 0;
-//		for(DecoratedNetwork net : state.getNetworkList()) {
-//			//abs
-//			f_eb += Math.abs(net.getTotalConsumption() - net.getTotalProduction());
-//		}
-//		//Average?
-//		f_eb /= state.getNetworkList().size();
-//		
-//		
-//		
-//		
-//		double f_maximum = 0;
-//		for(DecoratedNetwork net : state.getNetworkList()) {
-//			double prod = net.getTotalProduction();
-//			double con = net.getTotalConsumption();
-//			if(prod == 0 || con == 0) {
-//				f_maximum += lambda_max;
-//			}else {
-//				f_maximum += lambda_max * (Math.abs(prod - con)/Math.max(prod, con));				
-//			}
-//		}
-//		//Average?
-//		f_maximum /= state.getNetworkList().size();
-//		
-//		//calculate f_holon
-//		double f_holon = 0;
-//		for(DecoratedNetwork net : state.getNetworkList()) {
-//			double f_elements_deviation_production = net.getDeviationInProductionInNetworkForHolonObjects();
-//			double f_elements_deviation_consumption = net.getDeviationInConsumptionInNetworkForHolonObjects();
-//			double f_element = f_elements_deviation_production+f_elements_deviation_consumption;
-//			f_holon += f_element;
-//		}
-//		f_holon /= state.getNetworkList().size();
-//		
-//		//calculating f_selection
-//		double f_selection = calculateTopologieCost(state, amountOfAddedSwitch, addedCableMeters);
-//		//if(moreInformation)LOGGER.info("CostForWildcards:" + cost + ", CostSwitches(#" + amountOfAddedSwitch +"):" + cost_switch * amountOfAddedSwitch + ", CostCables(" +addedCableMeters+ "m):" + cost_of_cable_per_meter * addedCableMeters);
-//		
-//		
-//		//calculating f_grid
-//		double f_grid = 0;
-//		//each network is a holon
-//		for(DecoratedNetwork net: state.getNetworkList()) {
-//			Graph G = GraphMetrics.convertDecoratedNetworkToGraph(net);
-//			//We have to penalize single Networks;
-//			if(G.V.length <= 1 || G.S.length <= 1) {
-//				f_grid += lambda_avg_shortest_path;// + lambda_disjoint_path;
-//				continue;
-//			}
-//		
-//			double avgShortestPath = GraphMetrics.averageShortestDistance(G);
-//			//double disjpointPaths = GraphMetrics.averageEdgeDisjointPathProblem(G);
-//			if(useLog) {
-//				averageLog.addSample("avgShortestPath", (float)avgShortestPath);
-//			}
-//			f_grid += avgShortestPathPenalty(avgShortestPath);// + disjoinPathPenalty(disjpointPaths);
-//		}
-//		//take average to encourage splitting
-//		f_grid /= state.getNetworkList().size();
-//		
-//		
-//		
-//		
-//		if(moreInformation) {
-//			printWeightedValues(f_eb, f_maximum, f_holon, f_selection, f_grid);
-//			if(useLog) {
-//				log.info(averageLog.toString());
-//			}
-//		}
-//		//printUnsquashedValues(f_eb, f_maximum, f_holon, f_selection, f_grid);
-//		if(useLog) {
-//			averageLog.addSample("Unsquashed f_eb", (float)f_eb);
-//			averageLog.addSample("Unsquashed f_maximum", (float)f_maximum);
-//			averageLog.addSample("Unsquashed f_holon", (float)f_holon);
-//			averageLog.addSample("Unsquashed f_selection", (float)f_selection);
-//			averageLog.addSample("Unsquashed f_grid", (float)f_grid);
-//		}
-//		return (float) (w_eb * squash(f_eb, k_eb) 
-//				+ w_max * squash(f_maximum, k_max) 
-//				+ w_holon * squash(f_holon, k_holon) 
-//				+ w_selection * squash(f_selection, k_selection) 
-//				+ w_grid * squash(f_grid, k_grid));
-		return 0;
+
+
+		int holonCount = model.holons.size();
+		//Calculate f_eb the penalty for unbalenced energy in the network
+		double f_eb = 0;
+		for(Holon holon : model.holons) {
+			//abs
+			f_eb += Math.abs(holon.getTotalConsumption() - holon.getTotalProduction());
+		}
+		//Average
+		f_eb /= holonCount;
+
+
+
+
+		double f_maximum = 0;
+		for(Holon net : model.holons) {
+			double prod = net.getTotalProduction();
+			double con = net.getTotalConsumption();
+			if(prod == 0 || con == 0) {
+				f_maximum += lambda_max;
+			}else {
+				f_maximum += lambda_max * (Math.abs(prod - con)/Math.max(prod, con));
+			}
+		}
+		//Average?
+		f_maximum /= holonCount;
+
+		//calculate f_holon
+		double f_holon = 0;
+		for(Holon net : model.holons) {
+			double f_elements_deviation_production = net.getDeviationInProductionInNetworkForHolonObjects();
+			double f_elements_deviation_consumption = net.getDeviationInConsumptionInNetworkForHolonObjects();
+			double f_element = f_elements_deviation_production+f_elements_deviation_consumption;
+			f_holon += f_element;
+		}
+		f_holon /= holonCount;
+
+		//calculating f_selection
+		double f_selection = calculateTopologieCost(model, amountOfAddedSwitch, addedCableMeters);
+		//if(moreInformation)LOGGER.info("CostForWildcards:" + cost + ", CostSwitches(#" + amountOfAddedSwitch +"):" + cost_switch * amountOfAddedSwitch + ", CostCables(" +addedCableMeters+ "m):" + cost_of_cable_per_meter * addedCableMeters);
+
+
+		//calculating f_grid
+		double f_grid = 0;
+		//each network is a holon
+		for(Holon net : model.holons) {
+			GraphMetrics.Graph G = GraphMetrics.convertDecoratedNetworkToGraph(model, net);
+			//We have to penalize single Networks;
+			if(G.V.length <= 1 || G.S.length <= 1) {
+				f_grid += lambda_avg_shortest_path;// + lambda_disjoint_path;
+				continue;
+			}
+
+			double avgShortestPath = GraphMetrics.averageShortestDistance(G);
+			//double disjpointPaths = GraphMetrics.averageEdgeDisjointPathProblem(G);
+			if(useLog) {
+				averageLog.addSample("avgShortestPath", (float)avgShortestPath);
+			}
+			f_grid += avgShortestPathPenalty(avgShortestPath);// + disjoinPathPenalty(disjpointPaths);
+		}
+		//take average to encourage splitting
+		f_grid /= holonCount;
+
+
+
+
+		if(moreInformation) {
+			printWeightedValues(f_eb, f_maximum, f_holon, f_selection, f_grid);
+			if(useLog) {
+				log.info(averageLog.toString());
+			}
+		}
+		//printUnsquashedValues(f_eb, f_maximum, f_holon, f_selection, f_grid);
+		if(useLog) {
+			averageLog.addSample("Unsquashed f_eb", (float)f_eb);
+			averageLog.addSample("Unsquashed f_maximum", (float)f_maximum);
+			averageLog.addSample("Unsquashed f_holon", (float)f_holon);
+			averageLog.addSample("Unsquashed f_selection", (float)f_selection);
+			averageLog.addSample("Unsquashed f_grid", (float)f_grid);
+		}
+		return (float) (w_eb * squash(f_eb, k_eb)
+				+ w_max * squash(f_maximum, k_max)
+				+ w_holon * squash(f_holon, k_holon)
+				+ w_selection * squash(f_selection, k_selection)
+				+ w_grid * squash(f_grid, k_grid));
+	}
+	public static double calculateTopologieCost(Model model, int amountOfAddedSwitch,
+			double addedCableMeters) {
+		double cost = calculateWildcardCost(model);
+		cost += calculateAddedSwitchCost(amountOfAddedSwitch);
+		cost += calculateAddedCableCost(addedCableMeters);
+		return cost;
+	}
+
+	public static double calculateAddedCableCost(double addedCableMeters) {
+		return cost_of_cable_per_meter * addedCableMeters;
+	}
+
+	public static double calculateAddedSwitchCost(int amountOfAddedSwitch) {
+		return cost_switch * amountOfAddedSwitch;
+	}
+
+	public static double calculateWildcardCost(Model model) {
+		double cost = 0;
+		for(Holon net : model.holons) {
+			for(HolonObject hO : net.holonObjects) {
+				if(hO.getName().contains("Wildcard")){
+					if(hO.getName().length() > 9) {
+						String costString = hO.getName().substring(9);
+						cost += Double.parseDouble(costString);
+					}
+				}
+			}
+		}
+		return cost;
 	}
-//
-//	public static double calculateTopologieCost(DecoratedState state, int amountOfAddedSwitch,
-//			double addedCableMeters) {
-//		double cost = calculateWildcardCost(state);
-//		cost += calculateAddedSwitchCost(amountOfAddedSwitch);
-//		cost += calculateAddedCableCost(addedCableMeters);		
-//		return cost;
-//	}
-//
-//	public static double calculateAddedCableCost(double addedCableMeters) {
-//		return cost_of_cable_per_meter * addedCableMeters;
-//	}
-//
-//	public static double calculateAddedSwitchCost(int amountOfAddedSwitch) {
-//		return cost_switch * amountOfAddedSwitch;
-//	}
-//
-//	public static double calculateWildcardCost(DecoratedState state) {
-//		double cost = 0;
-//		for(DecoratedNetwork net : state.getNetworkList()) {
-//			for(DecoratedHolonObject dHobject : net.getConsumerList()) {
-//				if(dHobject.getModel().getName().contains("Wildcard")){
-//					if(dHobject.getModel().getName().length() > 9) {
-//						String costString = dHobject.getModel().getName().substring(9);
-//						cost += Double.parseDouble(costString);
-//					}
-//				}
-//			}
-//			for(DecoratedHolonObject dHobject : net.getConsumerSelfSuppliedList()) {
-//				if(dHobject.getModel().getName().contains("Wildcard")){
-//					if(dHobject.getModel().getName().length() > 9) {
-//						String costString = dHobject.getModel().getName().substring(9);
-//						cost += Double.parseDouble(costString);
-//					}
-//				}
-//			}
-//			for(DecoratedHolonObject dHobject : net.getSupplierList()) {
-//				if(dHobject.getModel().getName().contains("Wildcard")){
-//					if(dHobject.getModel().getName().length() > 9) {
-//						String costString = dHobject.getModel().getName().substring(9);
-//						cost += Double.parseDouble(costString);
-//					}
-//				}
-//			}
-//		}
-//		return cost;
-//	}
 
 	private static String doubleToString(double value) {
 		return String.format (Locale.US, "%.2f", value);

+ 2 - 2
src/holeg/api/AlgorithmFrameworkFlex.java

@@ -521,7 +521,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 	
 	private void run() {
 		cancel = false;
-		control.guiSetEnabled(true);
+		control.guiSetEnabled(false);
 		runPrinter.openStream();
 		runPrinter.println("");
 		runPrinter.println("Start:" + stringStatFromRunValues(getRunValuesFromActualState()));
@@ -540,7 +540,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn{
 		}
 		updateVisual();
 		runProgressbar.finishedCancel();
-		control.guiSetEnabled(false);
+		control.guiSetEnabled(true);
 		if(this.useEmailNotification && !cancel) {
 			EmailNotification.sendEmail(this.getClass().getName() + " finished", "Execution done.");
 		}

+ 2 - 2
src/holeg/api/TopologieAlgorithmFramework.java

@@ -513,7 +513,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 	
 	private void run() {
 		cancel = false;
-		control.guiSetEnabled(true);
+		control.guiSetEnabled(false);
 		runPrinter.openStream();
 		runPrinter.println("");
 		runPrinter.println("Start:" + stringStatFromActualState());
@@ -533,7 +533,7 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 		TopologieObjectiveFunction.averageLog.clear();
 		updateVisual();
 		runProgressbar.finishedCancel();
-		control.guiSetEnabled(false);
+		control.guiSetEnabled(true);
 	}
 	@SuppressWarnings("rawtypes")
 	private void initParameterStepping() {

+ 0 - 2
src/holeg/model/AbstractCanvasObject.java

@@ -4,7 +4,6 @@ import holeg.ui.model.IdCounter;
 import holeg.utility.math.vector.Vec2i;
 
 import java.util.Optional;
-import java.util.logging.Logger;
 
 /**
  * The abstract class "CpsObject" represents any possible object in the system
@@ -14,7 +13,6 @@ import java.util.logging.Logger;
  * @author Gruppe14
  */
 public abstract class AbstractCanvasObject {
-    private static final Logger log = Logger.getLogger(AbstractCanvasObject.class.getName());
     /* Name given by the user. */
     String name = "";
     /* Path of the image for the Obj. */

+ 3 - 20
src/holeg/model/Constrain.java

@@ -5,8 +5,8 @@ import java.util.function.Predicate;
 import com.google.gson.annotations.Expose;
 
 public class Constrain {
-	private Predicate<Flexibility> constrainFunction;
-	private String name;
+	private final Predicate<Flexibility> constrainFunction;
+	private final String name;
 	
 	public Constrain(Predicate<Flexibility> constrainFunction,String name) {
 		this.constrainFunction = constrainFunction;
@@ -33,22 +33,5 @@ public class Constrain {
 	public static Constrain createOffConstrain() {
 		return new Constrain( offConstrain, "offConstrain");
 	}
-	
-	
-	
-	/**
-	 * TODO(Tom2022-01-25): Delete me ....
-	 * @return
-	 */
-	public boolean fixJson() {
-		if(name.equals("onConstrain")) {
-			constrainFunction = onConstrain;
-			return false;
-		}else if(name.equals("offConstrain")){
-			constrainFunction = offConstrain;
-			return false;
-		}else {
-			return false;
-		}
-	}
+
 }

+ 119 - 5
src/holeg/model/Holon.java

@@ -6,6 +6,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 public class Holon {
     private static final Logger log = Logger.getLogger(Holon.class.getName());
@@ -59,11 +60,6 @@ public class Holon {
         Map<Boolean, List<HolonObject>> partition = holonObjects.stream().collect(Collectors.partitioningBy(hO -> hO.getActualEnergy() > 0));
         List<HolonObject> supplierList = partition.get(true);
         List<HolonObject> consumerList = partition.get(false);
-//        log.info("Supplier [" + supplierList.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
-//                "Consumer [" + consumerList.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
-//        );
-
-        // Sort SupplierList according to the EnergyToSupplyNetwork maximum first.
         supplierList.sort((a, b) -> -Float.compare(a.getActualEnergy(), b.getActualEnergy()));
         log.info("Supplier [" + supplierList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
                 "Consumer [" + consumerList.stream().map(hO -> hO.getName() + hO.getMinimumConsumingElementEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
@@ -173,4 +169,122 @@ public class Holon {
         consumer.setEnergyFromHolon(consumer.getEnergyFromHolon() + energy);
         supplier.setEnergyToHolon(supplier.getEnergyToHolon() + energy);
     }
+
+
+    public Stream<Float> getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork() {
+
+        return holonObjects.stream().flatMap(HolonObject::elementsStream)
+                .filter(ele -> (ele.flexList.stream().anyMatch(flex -> flex.offered)))
+                .map(ele -> -ele.getActualEnergy());
+    }
+
+    public Stream<Float> getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork() {
+        return getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork().filter(value -> (value > 0.f));
+    }
+
+    public Stream<Float> getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork() {
+        return getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork().filter(value -> (value < 0.f))
+                .map(value -> -value);
+    }
+
+    public float getFlexibilityProductionCapacity() {
+        return getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork().reduce(0.f, Float::sum);
+    }
+
+    public float getFlexibilityConsumptionCapacity() {
+        return getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork().reduce(0.f, Float::sum);
+    }
+
+    public int getAmountOfProductionFlexibilities() {
+        return (int)getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork().count();
+    }
+
+    public int getAmountOfConsumptionFlexibilities() {
+        return (int)getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork().count();
+    }
+
+    public float getAverageFlexibilityProduction() {
+        int amount = getAmountOfProductionFlexibilities();
+        return (amount > 0) ? getFlexibilityProductionCapacity() / (float) amount : 0.f;
+    }
+
+    public float getAverageFlexibilityConsumption() {
+        int amount = getAmountOfConsumptionFlexibilities();
+        return (amount > 0) ? getFlexibilityConsumptionCapacity() / (float) amount : 0.f;
+    }
+
+    public float getVarianzInFlexibilitiesConsumption() {
+        float average = getAverageFlexibilityConsumption();
+        float sum = getListOfEnergyInConsumptionThatIsOfferedByFlexibilitiesInThisNetwork()
+                .map(energy -> squared(energy - average)).reduce(0.f, Float::sum);
+        int amountOfFlexibilities = getAmountOfConsumptionFlexibilities();
+        return (amountOfFlexibilities > 0) ? sum / (float) amountOfFlexibilities : 0.f;
+    }
+
+    public float getVarianzInFlexibilitieProduction() {
+        float average = getAverageFlexibilityProduction();
+        float sum = getListOfEnergyInProductionThatIsOfferedByFlexibilitiesInThisNetwork()
+                .map(energy -> squared(energy - average)).reduce(0.f, Float::sum);
+        int amountOfFlexibilities = getAmountOfProductionFlexibilities();
+        return (amountOfFlexibilities > 0) ? sum / (float) amountOfFlexibilities : 0.f;
+    }
+
+    public float getDiviationInFlexibilityConsumption() {
+        return (float) Math.sqrt(getVarianzInFlexibilitiesConsumption());
+    }
+
+    public float getDiviationInFlexibilityProduction() {
+        return (float) Math.sqrt(getVarianzInFlexibilitieProduction());
+    }
+
+    public float getTotalConsumption() {
+        return holonObjects.stream().map(HolonObject::getConsumption).reduce(0.f, Float::sum);
+    }
+
+    public float getAverageConsumptionInNetworkForHolonObject() {
+        return getTotalConsumption() / (float) holonObjects.size();
+    }
+
+    public float getTotalProduction() {
+        return holonObjects.stream().map(HolonObject::getProduction).reduce(0.f, Float::sum);
+    }
+
+    public float getAverageProductionInNetworkForHolonObject() {
+        return getTotalProduction() / (float) holonObjects.size();
+    }
+
+    /**
+     * returns the Varianz in Poduction
+     *
+     * @return
+     */
+    public float getVarianzInProductionInNetworkForHolonObjects() {
+        float average = getAverageProductionInNetworkForHolonObject();
+        float sum = holonObjects.stream().map(hO -> squared(hO.getProduction() - average)).reduce(0.f, Float::sum);
+        return sum / (float) holonObjects.size();
+    }
+
+    public float getDeviationInProductionInNetworkForHolonObjects() {
+        return (float) Math.sqrt(getVarianzInProductionInNetworkForHolonObjects());
+    }
+
+    public float getVarianzInConsumptionInNetworkForHolonObjects() {
+        float average = getAverageConsumptionInNetworkForHolonObject();
+        float sum = holonObjects.stream().map(hO -> squared(hO.getConsumption() - average)).reduce(0.f, Float::sum);
+        return sum / (float) holonObjects.size();
+    }
+
+    public float getDeviationInConsumptionInNetworkForHolonObjects() {
+        return (float) Math.sqrt(getVarianzInConsumptionInNetworkForHolonObjects());
+    }
+
+
+    // Help Function
+    private float squared(float input) {
+        return input * input;
+    }
+
+    public int getAmountOfElements() {
+        return (int) holonObjects.stream().flatMap(HolonObject::elementsStream).count();
+    }
 }

+ 17 - 14
src/holeg/model/HolonObject.java

@@ -24,8 +24,8 @@ public class HolonObject extends AbstractCanvasObject implements PostDeserialize
     private transient float energyToHolon;
     private transient float minimumConsumingElementEnergy;
     private transient float energyNeededFromHolon;
-    private transient float energyFromConsumingElements;
-    private transient float energySelfSupplied;
+    private transient float consumption;
+    private transient float production;
 
     /**
      * Constructor Set by default the name of the object equals to the category
@@ -149,7 +149,7 @@ public class HolonObject extends AbstractCanvasObject implements PostDeserialize
      * @return The Energy of the consuming HolonElements.
      */
     public float getEnergyNeededFromConsumingElements() {
-        return energyFromConsumingElements;
+        return consumption;
     }
 
     /**
@@ -199,8 +199,8 @@ public class HolonObject extends AbstractCanvasObject implements PostDeserialize
         actualEnergy = elements.stream().map(HolonElement::getActualEnergy).reduce(0f, Float::sum);
         minimumConsumingElementEnergy = elements.stream().filter(element -> element.getActualEnergy() < 0).map(element -> -element.getActualEnergy()).min(Float::compare).orElse(0.0f);
         energyNeededFromHolon = (actualEnergy >= 0) ? 0 : -actualEnergy;
-        energyFromConsumingElements = elements.stream().filter(element -> element.getActualEnergy() < 0).map(element -> -element.getActualEnergy()).reduce(0.0f, Float::sum);
-        energySelfSupplied = elements.stream().map(HolonElement::getActualEnergy).filter(energy -> energy > 0).reduce(0.0f, Float::sum);
+        consumption = elements.stream().filter(element -> element.getActualEnergy() < 0).map(element -> -element.getActualEnergy()).reduce(0.0f, Float::sum);
+        production = elements.stream().map(HolonElement::getActualEnergy).filter(energy -> energy > 0).reduce(0.0f, Float::sum);
         energyToHolon = energyFromHolon = 0;
     }
 
@@ -212,8 +212,11 @@ public class HolonObject extends AbstractCanvasObject implements PostDeserialize
         return state;
     }
 
-    void setState(HolonObjectState state) {
-        this.state = state;
+    public boolean isProducer(){
+        return getProduction() > getConsumption();
+    }
+    public boolean isConsumer(){
+        return getConsumption() > getProduction();
     }
 
     public float getEnergyFromHolon() {
@@ -228,9 +231,9 @@ public class HolonObject extends AbstractCanvasObject implements PostDeserialize
         return energyNeededFromHolon;
     }
 
-
-    public float getEnergySelfSupplied() {
-        return energySelfSupplied;
+    public float getConsumption() { return consumption;}
+    public float getProduction() {
+        return production;
     }
 
     public float getCurrentEnergy() {
@@ -238,7 +241,7 @@ public class HolonObject extends AbstractCanvasObject implements PostDeserialize
     }
 
     public float getSupplyBarPercentage() {
-        return (energyFromConsumingElements > 0.001) ? (energyFromHolon + energySelfSupplied) / energyFromConsumingElements : 1.0f;
+        return (consumption > 0.001) ? (energyFromHolon + production) / consumption : 1.0f;
     }
 
     public String toString() {
@@ -258,11 +261,11 @@ public class HolonObject extends AbstractCanvasObject implements PostDeserialize
             state = HolonObjectState.PRODUCER;
         }else if(elements.isEmpty()){
             state = HolonObjectState.NO_ENERGY;
-        }else if(energySelfSupplied + energyFromHolon > energyFromConsumingElements) {
+        }else if(production + energyFromHolon > consumption) {
             state = (HolonObjectState.OVER_SUPPLIED);
-        }else if(energySelfSupplied + energyFromHolon == energyFromConsumingElements) {
+        }else if(production + energyFromHolon == consumption) {
             state = (HolonObjectState.SUPPLIED);
-        }else if(energySelfSupplied + energyFromHolon >= minimumConsumingElementEnergy) {
+        }else if(production + energyFromHolon >= minimumConsumingElementEnergy) {
             state = (HolonObjectState.PARTIALLY_SUPPLIED);
         }else {
             state = (HolonObjectState.NOT_SUPPLIED);

+ 3 - 0
src/holeg/preferences/PreferenceKeys.java

@@ -16,4 +16,7 @@ public class PreferenceKeys {
         public static final String FromEmail = "FromEmail";
         public static final String ToEmail = "ToEmail";
     }
+    public static class Category{
+        public static final String DefaultCategory = "DefaultCategory";
+    }
 }

+ 63 - 0
src/holeg/serialize/CategoryAdapter.java

@@ -0,0 +1,63 @@
+package holeg.serialize;
+
+import com.google.gson.*;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import holeg.model.AbstractCanvasObject;
+import holeg.model.Edge;
+import holeg.model.HolonObject;
+import holeg.model.HolonSwitch;
+import holeg.ui.view.category.Category;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+public class CategoryAdapter implements JsonSerializer<Category>, JsonDeserializer<Category> {
+    public static final Gson Gson = initGson();
+    public static final Type CategorySet = new TypeToken<Set<Category>>(){}.getType();
+    private static final Type HolonObjectList = new TypeToken<List<HolonObject>>(){}.getType();
+    private static final Type HolonSwitchList = new TypeToken<List<HolonSwitch>>(){}.getType();
+
+
+    private static Gson initGson() {
+        GsonBuilder gson = new GsonBuilder();
+        gson.registerTypeAdapter(Category.class, new CategoryAdapter());
+        gson.registerTypeAdapterFactory(new PostDeserializeEnabler());
+        gson.serializeNulls();
+        return gson.create();
+    }
+
+    @Override
+    public JsonElement serialize(Category src, Type typeOfSrc, JsonSerializationContext context) {
+        JsonObject object = new JsonObject();
+        object.addProperty("name", src.getName());
+
+        Map<Class<?>, List<AbstractCanvasObject>> map =
+                src.getObjects().stream()
+                        .collect(Collectors.groupingBy(Object::getClass));
+        object.add("objects", context.serialize(map.get(HolonObject.class), HolonObjectList));
+        object.add("switches", context.serialize(map.get(HolonSwitch.class), HolonSwitchList));
+        return object;
+    }
+
+    @Override
+    public Category deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+        JsonObject object = json.getAsJsonObject();
+        Category cat = new Category(object.get("name").getAsString());
+        if(object.has("objects") && !object.get("objects").isJsonNull()){
+            cat.getObjects().addAll(context.deserialize(object.getAsJsonArray("objects"), HolonObjectList));
+        }
+        if(object.has("switches") && !object.get("switches").isJsonNull()){
+            cat.getObjects().addAll(context.deserialize(object.getAsJsonArray("switches"), HolonSwitchList));
+        }
+        return cat;
+    }
+}

+ 0 - 1
src/holeg/serialize/ModelDeserializer.java

@@ -30,7 +30,6 @@ public class ModelDeserializer implements JsonDeserializer<Model>{
 
     @Override
     public Model deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
-        log.info("ModelDeserializer");
         JsonObject jsonObj = json.getAsJsonObject();
 
         Model model = new Model();

+ 29 - 14
src/holeg/ui/controller/Control.java

@@ -2,6 +2,8 @@ package holeg.ui.controller;
 
 import holeg.model.*;
 import holeg.preferences.ImagePreference;
+import holeg.preferences.PreferenceKeys;
+import holeg.serialize.CategoryAdapter;
 import holeg.ui.model.GuiSettings;
 import holeg.ui.model.IdCounter;
 import holeg.ui.view.category.Category;
@@ -17,6 +19,7 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.util.*;
 import java.util.logging.Logger;
+import java.util.prefs.Preferences;
 import java.util.stream.Collectors;
 
 import static holeg.serialize.ModelDeserializer.gson;
@@ -27,6 +30,7 @@ import static holeg.serialize.ModelDeserializer.gson;
  */
 public class Control {
     private static final Logger log = Logger.getLogger(Control.class.getName());
+    private static final Preferences prefs = Preferences.userNodeForPackage(Control.class);
     private final CanvasController canvasController;
     private final SimulationManager simulationManager;
     public Event OnCategoryChanged = new Event();
@@ -51,9 +55,9 @@ public class Control {
      * init default category and objects.
      */
     public void resetCategories() {
-        clearCategories();
+        GuiSettings.getCategories().clear();
         initCategories();
-        saveCategory();
+        saveCategories();
     }
 
     /**
@@ -70,7 +74,8 @@ public class Control {
      */
     public void addObject(Category cat, String obj, List<HolonElement> list, String img) {
         addNewHolonObject(cat, obj, list, img);
-        saveCategory();
+        OnCategoryChanged.broadcast();
+        saveCategories();
     }
 
     /**
@@ -81,12 +86,13 @@ public class Control {
      */
     public void addSwitch(Category cat, String obj) {
         addNewHolonSwitch(cat, obj);
-        saveCategory();
+        OnCategoryChanged.broadcast();
+        saveCategories();
     }
 
     public void deleteCategory(Category category) {
         removeCategory(category);
-        saveCategory();
+        saveCategories();
     }
 
     /**
@@ -240,10 +246,6 @@ public class Control {
     }
 
 
-    public void saveCategory() {
-        //TODO(Tom2022-01-27):
-    }
-
 
     /**
      * Getter for Model.
@@ -295,7 +297,6 @@ public class Control {
 
 
     public void guiSetEnabled(boolean state) {
-        log.info("guiDisabled");
         OnGuiSetEnabled.broadcast(state);
     }
 
@@ -303,7 +304,7 @@ public class Control {
     /**
      * init default category and objects.
      */
-    public void initCategories() {
+    private void initCategories() {
         Category energy = createCategoryWithName("Energy");
         Category building = createCategoryWithName("Building");
         Category component = createCategoryWithName("Component");
@@ -356,9 +357,6 @@ public class Control {
         OnCategoryChanged.broadcast();
     }
 
-    public void clearCategories() {
-        GuiSettings.getCategories().clear();
-    }
 
     /**
      * Add Object into a Category.
@@ -483,4 +481,21 @@ public class Control {
         OnShowGroupNode.broadcast(groupNode);
         clearSelection();
     }
+
+
+    public void loadCategory(){
+        String json = prefs.get(PreferenceKeys.Category.DefaultCategory, "Init");
+        if(json.equals("Init")){
+            initCategories();
+            return;
+        }
+        GuiSettings.getCategories().clear();
+        GuiSettings.getCategories().addAll(CategoryAdapter.Gson.fromJson(json, CategoryAdapter.CategorySet));
+        OnCategoryChanged.broadcast();
+
+    }
+    public void saveCategories(){
+        String json = CategoryAdapter.Gson.toJson(GuiSettings.getCategories());
+        prefs.put(PreferenceKeys.Category.DefaultCategory, json);
+    }
 }

+ 1 - 0
src/holeg/ui/view/Main.java

@@ -43,6 +43,7 @@ public class Main {
             Model model = new Model();
             Control control = new Control(model);
             Gui view = new Gui(control);
+            control.loadCategory();
             view.setVisible(true);
         });
     }

+ 24 - 28
src/holeg/ui/view/category/CategoryPanel.java

@@ -9,7 +9,7 @@ import holeg.ui.controller.Control;
 import holeg.ui.model.GuiSettings;
 import holeg.ui.view.canvas.Canvas;
 import holeg.ui.view.dialog.AddObjectPopUp;
-import holeg.ui.view.dialog.CreateNewDialog;
+import holeg.ui.view.dialog.NewCategoryDialog;
 import holeg.ui.view.image.Import;
 import holeg.ui.view.main.Gui;
 
@@ -20,7 +20,6 @@ import javax.swing.tree.TreeCellRenderer;
 import java.awt.*;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.logging.Logger;
 
@@ -42,6 +41,8 @@ public class CategoryPanel extends JScrollPane {
 
 
     private final JTree categoryTree = new JTree();
+    private Category actualSelectedCategory = null;
+
 
     public CategoryPanel(Control control, Gui gui) {
         this.control = control;
@@ -76,7 +77,7 @@ public class CategoryPanel extends JScrollPane {
         newMenu.add(mItemSwitch);
         editItem.addActionListener(clicked -> getSelectedNode().ifPresent(node -> {
             ObjectTreeNode objectNode = (ObjectTreeNode) node;
-            new AddObjectPopUp(control, objectNode.getObject(), objectNode.getCategory(), gui);
+            objectNode.openEdit();
         }));
         removeItem.addActionListener(clicked -> getSelectedNode().ifPresent(selectedNode -> {
             if (selectedNode instanceof CategoryTreeNode node) {
@@ -94,26 +95,12 @@ public class CategoryPanel extends JScrollPane {
     }
 
     private void initButtons() {
-        mItemCategory.addActionListener(clicked -> new CreateNewDialog(control, CreateNewDialog.Option.Category, gui));
-        mItemObject.addActionListener(clicked -> new CreateNewDialog(control, CreateNewDialog.Option.Object, gui));
-        mItemSwitch.addActionListener(clicked -> new CreateNewDialog(control, CreateNewDialog.Option.Switch, gui));
-    }
-
-    private void TryDeleteSelectedCategory() {
-        Optional<DefaultMutableTreeNode> selectedNode = Optional.ofNullable((DefaultMutableTreeNode) categoryTree.getLastSelectedPathComponent());
-        selectedNode.ifPresentOrElse(node -> {
-            if (node instanceof CategoryTreeNode catNode) {
-                int dialogResult = JOptionPane.showConfirmDialog(gui, "Do you really want to delete the Category " + catNode + "?",
-                        "Warning", JOptionPane.YES_NO_OPTION);
-                if (dialogResult == JOptionPane.YES_OPTION) {
-                    GuiSettings.getCategories().stream().filter(cat -> Objects.equals(cat.getName(), catNode.toString())).findAny()
-                            .ifPresent(control::deleteCategory);
-                }
-            } else if (node instanceof ObjectTreeNode objNode) {
-                objNode.getCategory().getObjects().remove(objNode.object);
-            }
-            categoryTree.repaint();
-        }, () -> JOptionPane.showMessageDialog(gui, "Please select a Category or an Object in the left library in order to delete something."));
+        mItemCategory.addActionListener(clicked -> new NewCategoryDialog(control, gui));
+        mItemObject.addActionListener(clicked -> new AddObjectPopUp(control, new HolonObject("Object"), actualSelectedCategory, gui));
+        mItemSwitch.addActionListener(clicked -> {
+            actualSelectedCategory.getObjects().add(new HolonSwitch("HolonSwitch"));
+            control.OnCategoryChanged.broadcast();
+        });
     }
 
 
@@ -154,7 +141,7 @@ public class CategoryPanel extends JScrollPane {
         }
     }
 
-    private static class CategoryTreeNode extends DefaultMutableTreeNode {
+    private class CategoryTreeNode extends DefaultMutableTreeNode {
         private final Category category;
 
         public CategoryTreeNode(Category category) {
@@ -168,7 +155,7 @@ public class CategoryPanel extends JScrollPane {
         }
     }
 
-    private static class ObjectTreeNode extends DefaultMutableTreeNode {
+    private class ObjectTreeNode extends DefaultMutableTreeNode {
         private final AbstractCanvasObject object;
         private final Category category;
 
@@ -181,10 +168,17 @@ public class CategoryPanel extends JScrollPane {
         public AbstractCanvasObject getObject() {
             return object;
         }
-
         public Category getCategory() {
             return category;
         }
+
+        public void openEdit(){
+            if(object instanceof HolonObject hO){
+                new AddObjectPopUp(control, hO, category, gui);
+            }else if(object instanceof HolonSwitch holonSwitch){
+                log.info("Edit Switch");
+            }
+        }
     }
 
     private class CategoryMouseListener extends MouseAdapter {
@@ -212,12 +206,14 @@ public class CategoryPanel extends JScrollPane {
         private void preparePopUpMenu(MouseEvent e) {
             categoryTree.setSelectionPath(categoryTree.getPathForLocation(e.getX(), e.getY()));
             getSelectedNode().ifPresent(selectedNode -> {
-                if (selectedNode instanceof CategoryTreeNode) {
+                if (selectedNode instanceof CategoryTreeNode node) {
+                    actualSelectedCategory = node.getCategory();
                     mItemObject.setVisible(true);
                     mItemSwitch.setVisible(true);
                     editItem.setVisible(false);
                     removeItem.setVisible(true);
-                } else if (selectedNode instanceof ObjectTreeNode) {
+                } else if (selectedNode instanceof ObjectTreeNode node) {
+                    actualSelectedCategory = node.getCategory();
                     mItemSwitch.setVisible(true);
                     mItemObject.setVisible(true);
                     editItem.setVisible(true);

+ 2 - 14
src/holeg/ui/view/dialog/AddElementPopUp.java

@@ -30,10 +30,6 @@ import holeg.ui.view.image.Import;
  */
 public class AddElementPopUp extends JDialog {
 
-	/**
-	 * Serial.
-	 */
-	private static final long serialVersionUID = 1L;
 	/* Data */
 	/** Holon Object the Element should be added to */
 	private HolonObject tempCps;
@@ -44,16 +40,12 @@ public class AddElementPopUp extends JDialog {
 	/** Panel containing everything */
 	private final JPanel contentPanel = new JPanel();
 	/** Textfield for entering a Name for the Element */
-	private JTextField elementName;
+	private final JTextField elementName;
 	/** Textfield for the energy the Element consumes/produces */
-	private JTextField providedEnergy;
+	private final JTextField providedEnergy;
 	/** Element is active if checked */
 	JCheckBox checkBoxActive;
 
-	/**
-	 * Create the AddElementPopup Dialog
-	 * @param parentFrame
-	 */
 	AddElementPopUp(JFrame parentFrame) {
 		super((java.awt.Frame) null, true);
 		this.setIconImage(Import.loadImage(ImagePreference.Logo, 30, 30));
@@ -144,10 +136,6 @@ public class AddElementPopUp extends JDialog {
 		return hl;
 	}
 
-	/**
-	 * setElement that should be edited
-	 * @param holonElement
-	 */
 	public void setElement(HolonElement holonElement) {
 		hl = holonElement;
 		elementName.setText(hl.getName());

+ 8 - 10
src/holeg/ui/view/dialog/AddObjectPopUp.java

@@ -19,6 +19,7 @@ import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.io.*;
 import java.util.ArrayList;
+import java.util.logging.Logger;
 
 /**
  * Popup for adding a Holon Object to a Category.
@@ -26,6 +27,7 @@ import java.util.ArrayList;
  * @author Gruppe14
  */
 public class AddObjectPopUp extends JDialog {
+	private static final Logger log = Logger.getLogger(AddObjectPopUp.class.getName());
 	private AddElementPopUp addElement;
 	private final JTextField objectName;
 	private final JTextField sourcePath;
@@ -46,7 +48,7 @@ public class AddObjectPopUp extends JDialog {
 	 * @param obj  the object
 	 * @param category  the categorie
 	 */
-	public AddObjectPopUp(Control control, AbstractCanvasObject obj, Category category, JFrame parentFrame) {
+	public AddObjectPopUp(Control control, HolonObject obj, Category category, JFrame parentFrame) {
 		this.control = control;
 		toEdit = obj;
 		this.setIconImage(Import.loadImage(ImagePreference.Logo, 30, 30));
@@ -122,14 +124,13 @@ public class AddObjectPopUp extends JDialog {
 					sourcePath.setBackground(Color.WHITE);
 				}
 			});
-			if (true) {
+			if (!obj.getImagePath().equals("")) {
+				log.info("IMAGEPATH:" + obj.getImagePath());
 				lblImagePreview.setIcon(new ImageIcon(Import.loadImage(obj.getImagePath(), 50, 50)));
-			}
-			sourcePath.setBounds(148, 77, 271, 20);
-			if (true) {
 				this.filePath = obj.getImagePath();
 				sourcePath.setText(filePath);
 			}
+			sourcePath.setBounds(148, 77, 271, 20);
 			contentPanel.add(sourcePath);
 
 			sourcePath.setColumns(10);
@@ -168,11 +169,7 @@ public class AddObjectPopUp extends JDialog {
 				scrollPane.setViewportView(list);
 			}
 		}
-		if (true) {
-			((HolonObject) obj).elementsStream().forEach(hE -> {
-				addElement(hE);
-			});
-		}
+			obj.elementsStream().forEach(this::addElement);
 		{
 			JButton btnNewButton = new JButton("Delete Element");
 			btnNewButton.addActionListener(actionEvent -> {
@@ -268,6 +265,7 @@ public class AddObjectPopUp extends JDialog {
 		OutputStream outStream;
 		try {
 			File source = new File(filePath);
+			//TODO: "CopieFile"
 			File dest = new File(System.getProperty("user.home") + "/.config/HolonGUI/Images/");
 			dest.mkdirs();
 			dest = new File(dest, selectedFile.getName());

+ 0 - 251
src/holeg/ui/view/dialog/CreateNewDialog.java

@@ -1,251 +0,0 @@
-package holeg.ui.view.dialog;
-
-import java.awt.BorderLayout;
-import java.awt.CardLayout;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.GridLayout;
-import java.util.logging.Logger;
-
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-import holeg.model.HolonObject;
-import holeg.model.Model;
-import holeg.ui.controller.Control;
-
-
-
-public class CreateNewDialog extends JDialog{
-	//DefaultConstructor
-	String[] optionStrings = { "","Category", "Object", "Switch"};
-	private static final Logger log = Logger.getLogger(CreateNewDialog.class.getName());
-
-	public static enum Option {
-		None, Category, Object, Switch;
-		public static Option getEnumAtIndex(int desired){
-			if(desired>=0 && desired<=4)
-				return values()[desired];
-			else 
-				return None;
-		}
-		
-	};
-	Option actualOption = Option.None;
-	Control actualController;
-	
-	//important JPanelItems
-	JComboBox<String> optionList = new JComboBox<String>(optionStrings);
-	JTextField inputName = new JTextField();
-	JButton saveButton = new JButton("Save");
-	JTextField inputNameSwitch = new JTextField();
-	JComboBox<String> selectedCategorySwitch = new JComboBox<String>();
-	
-	
-	
-	public CreateNewDialog(Control controller, JFrame parentFrame){
-		super((JFrame)parentFrame, "Create a..");
-		actualController = controller;
-		setVisible(true);
-		JPanel contentPanel = new JPanel();
-		contentPanel.setLayout(new BorderLayout());
-		contentPanel.add(makeTopPanel(), BorderLayout.PAGE_START);
-		JPanel cards = new JPanel(new CardLayout());
-		cards.add(makeNothingPanel(), Option.None.name());
-		cards.add(makeCategoryPanel(), Option.Category.name());
-		cards.add(makeObjectPanel(), Option.Object.name());
-		cards.add(makeSwitchPanel(), Option.Switch.name());
-		contentPanel.add(cards, BorderLayout.CENTER);
-		
-		optionList.addActionListener(actionEvent -> {
-			CardLayout cl = (CardLayout)(cards.getLayout());
-			actualOption = Option.getEnumAtIndex(optionList.getSelectedIndex());
-		    cl.show(cards, actualOption.name());
-		    saveButton.setEnabled(actualOption != Option.None);  
-		    saveButton.setVisible(actualOption != Option.Object);	
-		});
-		
-		
-        contentPanel.add(makeBottemPanel(), BorderLayout.PAGE_END);
-        addSaveButtonLogik();
-        add(contentPanel);
-        saveButton.setEnabled(false);	
-		setMinimumSize(new Dimension(400,50));
-		pack();
-		setLocationRelativeTo(parentFrame);
-	}
-
-
-	public CreateNewDialog(Control controller, Option aOption, JFrame parentFrame){
-		super((JFrame)parentFrame, "Create a " + aOption.name());
-		actualController = controller;
-		if(aOption == Option.None)
-			dispose();
-		setVisible(true);
-		JPanel contentPanel = new JPanel();
-		contentPanel.setLayout(new BorderLayout());
-		JPanel content;
-		switch(aOption)
-		{
-		case Category:
-			content = makeCategoryPanel();
-			break;
-		case Object:
-			content = makeObjectPanel();
-			break;
-		case Switch:
-			content = makeSwitchPanel();
-			break;
-		default:
-			content = makeNothingPanel();
-			break;
-		}
-		actualOption = aOption;
-		contentPanel.add(content, BorderLayout.CENTER);
-		contentPanel.add(makeBottemPanel(), BorderLayout.PAGE_END);
-		addSaveButtonLogik(); 
-		//TODO(Tom2021-12-1) delete and make own iterface
-	    if(aOption == Option.Object) saveButton.setVisible(false);
-		add(contentPanel);	
-		setMinimumSize(new Dimension(400,50));
-		pack();
-		setLocationRelativeTo(parentFrame);
-	}
-	
-	
-	private JPanel makeTopPanel() {
-		JPanel topPanel = new JPanel(new GridLayout(1,2));
-		JLabel text = new JLabel("Choose..");
-		topPanel.add(text);
-		topPanel.add(optionList);
-		return topPanel;
-	}
-
-	private JPanel makeBottemPanel() {
-		JPanel bottomPanel = new JPanel();
-        bottomPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
-       
-        bottomPanel.add(saveButton);
-        JButton cancelButton = new JButton("Cancel");
-        cancelButton.addActionListener(actionEvent -> dispose());
-        bottomPanel.add(cancelButton);
-		return bottomPanel;
-	}
-
-	private JPanel makeObjectPanel() {
-		JPanel objectPanel = new JPanel();
-		JLabel categoryText = new JLabel("In Category:");
-		objectPanel.add(categoryText);
-		JComboBox<String> selectedCategory = new JComboBox<String>(actualController.getCategoriesStrings());
-		objectPanel.add(selectedCategory);
-		
-		
-		JButton nextButton = new JButton("Next");
-		objectPanel.add(nextButton);
-		nextButton.addActionListener(actionEvent -> {
-			makeOldObjectPopUp(selectedCategory.getSelectedItem().toString());
-		});
-		return objectPanel;
-	}
-
-	private void makeOldObjectPopUp(String categoryName) {
-		//TODO(Tom2021-12-1): del and make own on
-		log.warning("TODO");
-//
-//		HolonObject hO = new HolonObject("");
-//
-//		AddObjectPopUp addObjectPopUP = new AddObjectPopUp(false,hO , "hei", null);
-//		addObjectPopUP.setVisible(true);
-//		addObjectPopUP.setController(actualController);
-//		addObjectPopUP.setCategory(categoryName);
-//		dispose();
-	}
-
-
-	private JPanel makeNothingPanel() {
-		return new JPanel();
-	}
-	
-	private JPanel makeCategoryPanel()
-	{
-		JPanel newCategory = new JPanel(new FlowLayout());
-		JLabel categoryName = new JLabel("Name:");
-		String initialText = "The name of the new category";
-		inputName.setText(initialText);
-		inputName.setBackground(java.awt.Color.LIGHT_GRAY);
-		inputName.addFocusListener(new java.awt.event.FocusAdapter() {
-		    public void focusGained(java.awt.event.FocusEvent evt) {
-		       if (inputName.getText().equals(initialText)) {
-		    	   inputName.setText("");
-		    	   inputName.setBackground(java.awt.Color.WHITE);
-		       }
-		    }
-		    public void focusLost (java.awt.event.FocusEvent evt) {
-			       if (inputName.getText().equals("")) {
-			    	   inputName.setText(initialText);
-			    	   inputName.setBackground(java.awt.Color.LIGHT_GRAY);
-			       }
-			    }
-		});
-		inputName.setColumns(20);
-		newCategory.add(categoryName);
-		newCategory.add(inputName);
-		return newCategory;
-	}
-	private JPanel makeSwitchPanel()
-	{
-		JPanel objectPanel = new JPanel();
-		JLabel categoryText = new JLabel("In Category:");
-		objectPanel.add(categoryText);
-		selectedCategorySwitch = new JComboBox<String>(actualController.getCategoriesStrings());
-		objectPanel.add(selectedCategorySwitch);
-		
-		
-		JLabel switchName = new JLabel("Name:");
-		String initialText = "The name of the new switch";
-		
-		inputNameSwitch.setText(initialText);
-		inputNameSwitch.setBackground(java.awt.Color.LIGHT_GRAY);
-		inputNameSwitch.addFocusListener(new java.awt.event.FocusAdapter() {
-		    public void focusGained(java.awt.event.FocusEvent evt) {
-		       if (inputNameSwitch.getText().equals(initialText)) {
-		    	   inputNameSwitch.setText("");
-		    	   inputNameSwitch.setBackground(java.awt.Color.WHITE);
-		       }
-		    }
-		    public void focusLost (java.awt.event.FocusEvent evt) {
-			       if (inputNameSwitch.getText().equals("")) {
-			    	   inputNameSwitch.setText(initialText);
-			    	   inputNameSwitch.setBackground(java.awt.Color.LIGHT_GRAY);
-			       }
-			    }
-		});
-		inputNameSwitch.setColumns(20);
-		objectPanel.add(switchName);
-		objectPanel.add(inputNameSwitch);
-		return objectPanel;
-	}	
-	private void addSaveButtonLogik() {
-		saveButton.addActionListener(actionEvent -> {
-			if(actualOption == Option.Category)
-			{
-				actualController.createCategoryWithName(inputName.getText());
-
-				dispose();
-			}
-			else if (actualOption == Option.Switch)
-			{
-				actualController.findCategoryWithName(selectedCategorySwitch.getSelectedItem().toString()).ifPresent(cat -> {
-					actualController.addSwitch(cat, inputNameSwitch.getText());
-				});
-
-				dispose();
-			}
-		});
-	}
-}

+ 0 - 2
src/holeg/ui/view/dialog/CreateTemplatePopUp.java

@@ -34,8 +34,6 @@ import holeg.ui.view.image.Import;
  */
 public class CreateTemplatePopUp extends JDialog {
 
-	private static final long serialVersionUID = 1L;
-
 	/**
 	 * Template HolonObject
 	 */

+ 58 - 0
src/holeg/ui/view/dialog/NewCategoryDialog.java

@@ -0,0 +1,58 @@
+package holeg.ui.view.dialog;
+
+import holeg.ui.controller.Control;
+import holeg.ui.view.canvas.Canvas;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.logging.Logger;
+
+public class NewCategoryDialog extends JDialog {
+
+    private final JPanel contentPanel = new JPanel(new BorderLayout());
+    private final JPanel mainPanel = new JPanel();
+    private final JPanel buttonPanel = new JPanel();
+    private final JLabel categoryLabel = new JLabel("Category:");
+    private final JTextField nameTextField = new JTextField("Name");
+    private final JButton okayButton = new JButton("Okay");
+    private final JButton cancelButton = new JButton("Cancel");
+    private final Control control;
+
+    public NewCategoryDialog(Control control, JFrame parentFrame) {
+        super(parentFrame);
+        this.control = control;
+        init();
+        this.setVisible(true);
+        this.pack();
+        setLocationRelativeTo(parentFrame);
+    }
+
+    private void init() {
+        this.setTitle("Create new category");
+        initLayout();
+        initButtons();
+    }
+
+    private void initLayout() {
+        buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+        contentPanel.setPreferredSize(new Dimension(200, 60));
+        mainPanel.setLayout(new GridLayout(1, 2));
+        mainPanel.add(categoryLabel);
+        mainPanel.add(nameTextField);
+        okayButton.setDefaultCapable(true);
+        buttonPanel.add(okayButton);
+        buttonPanel.add(cancelButton);
+        contentPanel.add(mainPanel);
+        contentPanel.add(buttonPanel, BorderLayout.PAGE_END);
+
+        this.setContentPane(contentPanel);
+    }
+
+    private void initButtons() {
+        okayButton.addActionListener(clicked -> {
+            control.createCategoryWithName(nameTextField.getText());
+            dispose();
+        });
+        cancelButton.addActionListener(clicked -> dispose());
+    }
+}

+ 0 - 3
src/holeg/ui/view/image/Import.java

@@ -116,9 +116,6 @@ public class Import {
 
 		}
 	}
-
-	// Nobody needs an instance of this. I do, because I use it to load images from
-	// inside the JAR.
 	private Import() {
 	}
 }

+ 3 - 3
src/holeg/ui/view/inspector/UnitGraph.java

@@ -129,14 +129,14 @@ public class UnitGraph extends JPanel implements MouseListener, MouseMotionListe
 	}
 
 	public void setGlobalCurve(Set<HolonElement> elements) {
-		if(elements.isEmpty()) {
+		if( elements == null || elements.isEmpty()) {
 			this.globalCurve = null;
 			return;
 		}
 		GlobalCurve curve = new GlobalCurve();
-		curve.maxEnergy = elements.stream().map(ele -> ele.getEnergy()).filter(energy -> energy > 0).reduce(0.0f,
+		curve.maxEnergy = elements.stream().map(HolonElement::getEnergy).filter(energy -> energy > 0).reduce(0.0f,
 				Float::sum);
-		curve.minEnergy = elements.stream().map(ele -> ele.getEnergy()).filter(energy -> energy < 0).reduce(0.0f,
+		curve.minEnergy = elements.stream().map(HolonElement::getEnergy).filter(energy -> energy < 0).reduce(0.0f,
 				Float::sum);
 		Model model = control.getModel();
 		float[] sample = new float[model.getMaxIterations()];

+ 1 - 0
src/holeg/ui/view/main/Gui.java

@@ -84,6 +84,7 @@ public class Gui extends JFrame {
             prefs.putInt(PreferenceKeys.Gui.YPos, bounds.y);
             prefs.putInt(PreferenceKeys.Gui.Width, bounds.width);
             prefs.putInt(PreferenceKeys.Gui.Height, bounds.height);
+            control.saveCategories();
             if (JOptionPane.showConfirmDialog(this, "Are you sure you want to exit?", "HOLEG",
                     JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
                 System.exit(0);