Browse Source

Simulation Complete

TomTroppmann 2 years ago
parent
commit
9afa369e46

+ 7 - 3
build.gradle

@@ -5,9 +5,13 @@ group = 'holeg'
 version = '2.2.0'
 description = 'HOLEG'
 
-sourceSets.main.java.srcDirs = ['src']
-sourceSets.test.java.srcDirs = ['tests']
-
+java {
+    sourceSets {
+        main.java.srcDirs = ['src']
+        test.java.srcDirs = ['tests']
+    }
+    toolchain.languageVersion.set(JavaLanguageVersion.of(17))
+}
 application {
     mainClass = 'holeg.ui.view.main.Main'
 }

+ 0 - 1
src/holeg/addon/RandomOfferdFlexibility.java

@@ -324,7 +324,6 @@ public class RandomOfferdFlexibility implements AddOn {
 			return;
 		}
 		control.calculateStateAndVisualForCurrentTimeStep();
-		control.updateCanvas();
 		List<Flexibility> flexList = control.getModel().getAllFlexibilities();
 		List<Flexibility> allOfferedFlex = flexList.stream().filter(flex -> flex.getState().equals(FlexState.OFFERED)).toList();
 

+ 0 - 1
src/holeg/addon/RandomSwitch.java

@@ -71,7 +71,6 @@ public class RandomSwitch implements AddOn {
 			}
 		});
 		control.calculateStateAndVisualForCurrentTimeStep();
-		control.updateCanvas();
 	}
 	@Override
 	public JPanel getPanel() {

+ 0 - 3
src/holeg/addon/Randomizer.java

@@ -238,9 +238,6 @@ public class Randomizer implements AddOn {
 			
 		});
 		control.calculateStateAndVisualForCurrentTimeStep();
-		control.updateCanvas();
-		
-		
 	}
 
 	

+ 0 - 2
src/holeg/algorithm/binary/BaseLine.java

@@ -328,7 +328,6 @@ public class BaseLine implements AddOn {
 	/**
 	 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
 	 * Also initialize the Access Hashmap to swap faster positions.
-	 * @param ModelTest
 	 * @return
 	 */
 	private List<Boolean> extractPositionAndAccess() {
@@ -390,7 +389,6 @@ public class BaseLine implements AddOn {
 	 */
 	private void updateVisual() {
 		control.calculateStateAndVisualForCurrentTimeStep();
-		control.updateCanvas();
 	}
 	/**
 	 * Sets the Model back to its original State before the LAST run.

+ 0 - 2
src/holeg/algorithm/example/DemoAlgo.java

@@ -337,7 +337,6 @@ public class DemoAlgo implements AddOn {
 		/**
 		 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
 		 * Also initialize the Access Hashmap to swap faster positions.
-		 * @param ModelTest
 		 * @return
 		 */
 		private List<Boolean> extractPositionAndAccess() {
@@ -397,7 +396,6 @@ public class DemoAlgo implements AddOn {
 		 */
 		private void updateVisual() {
 			control.calculateStateAndVisualForCurrentTimeStep();
-			control.updateCanvas();
 		}
 		/**
 		 * Sets the Model back to its original State before the LAST run.

+ 4 - 9
src/holeg/api/TopologieAlgorithmFramework.java

@@ -702,8 +702,6 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 	/**
 	 * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects on the Canvas.
 	 * Also initialize the Access Hashmap to swap faster positions.
-	 * @param ModelTest
-	 * @return
 	 */
 	protected List<Integer> extractPositionAndAccess() {
 		Model model = control.getModel();
@@ -775,8 +773,6 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 	/**
 	 * Method to extract the Informations recursively out of the Model.
 	 * @param nodes
-	 * @param positionToInit
-	 * @param timeStep
 	 */
 	private void generateAccess(Stream<AbstractCanvasObject> nodes, GroupNode groupnode) {
 		nodes.forEach(aCps -> {
@@ -816,12 +812,11 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 	}
 	/**
 	 * All Nodes have to be in the access map !!
-	 * @param cables
 	 */
 	private void addCables(List<Edge> edges) {
 		
 		for (Edge edge : edges) {
-			edge.setUnlimitedCapacity(true);
+			edge.mode = Edge.EdgeMode.Unlimited;
 			edgeList.add(edge);
 			//console.println("Cable from " + edge.getA().getName() + " to " + edge.getB().getName());
 			if(!accessObjectToInt.containsKey(edge.getA())) {
@@ -882,18 +877,18 @@ public abstract class TopologieAlgorithmFramework implements AddOn{
 			this.switchList.add(newSwitch);
 			//Generate Cable From Object A To Switch
 			Edge edge1 = new Edge(fromObject, newSwitch, 0);
-			edge1.setUnlimitedCapacity(true);
+			edge1.mode = Edge.EdgeMode.Unlimited;
 			control.getModel().getEdgesOnCanvas().add(edge1);
 			edgeList.add(edge1);
 			
 			//Generate Cable From Object B To Switch
 			Edge edge = new Edge(newSwitch, toObject, 0);
-			edge.setUnlimitedCapacity(true);
+			edge.mode = Edge.EdgeMode.Unlimited;
 			control.getModel().getEdgesOnCanvas().add(edge);
 			edgeList.add(edge);
 			}else {
 			Edge edge = new Edge(accessIntToObject.get(cable.first), accessIntToObject.get(cable.second), 0);
-			edge.setUnlimitedCapacity(true);
+			edge.mode = Edge.EdgeMode.Unlimited;
 			control.getModel().getEdgesOnCanvas().add(edge);
 			edgeList.add(edge);
 		}

+ 75 - 107
src/holeg/model/Edge.java

@@ -2,13 +2,6 @@ package holeg.model;
 
 import com.google.gson.annotations.Expose;
 
-/**
- * The class "CpsEdge" represents the connections on the GUI. Each connection
- * contains a max. capacity, a flow, a status (isWorking), tags (for internal
- * use of electricity flow), source and destination
- *
- * @author Gruppe14
- */
 public class Edge {
 
     // Max. capacity of the Edge, if flow is greater than the status --> is
@@ -19,25 +12,9 @@ public class Edge {
     AbstractCanvasObject a;
     // Destination
     AbstractCanvasObject b;
-    @Expose
-    private boolean breakedManuel = false;
-    @Expose
-    private boolean unlimitedCapacity = false;
-    
-    
-    
-    
-    
-    /**
-     * Getter for the length of the Cable.
-     * Always calculate never saved.
-     * Needs to be profiled whats better.
-     * @return
-     */
-    public float getLength() {
-    	return a.getPosition().getDistance(b.getPosition());
-    }
-
+    public EdgeMode mode = EdgeMode.Normal;
+    private EdgeState state = initState();
+    private float flowEnergy = 0;
 
     /**
      * Constructor with a user-defined max. capacity
@@ -52,18 +29,24 @@ public class Edge {
         this.maxCapacity = maxCap;
     }
 
-    
+
     /**
      * Clone Constructor
-     *
-     * @param a      Source
-     * @param b      Destination
-     * @param maxCap Maximum Capacity
      */
     public Edge(Edge other) {
         setA(other.a);
         setB(other.b);
         this.maxCapacity = other.maxCapacity;
+        this.state = other.state;
+        this.mode = other.mode;
+        this.flowEnergy = other.flowEnergy;
+    }
+
+    /**
+     * Getter for the length of the Cable.
+     */
+    public float getLength() {
+        return a.getPosition().getDistance(b.getPosition());
     }
 
     /**
@@ -102,87 +85,72 @@ public class Edge {
         this.b = b;
     }
 
-
-
-    
     /**
      * Check if a CpsEdge is Connected to the AbstractCpsObject.
+     *
      * @param holonObject the AbstractCpsObject to check.
      * @return true if either a or b is the AbstractCpsObject to check.
      */
-    public boolean isConnectedTo(AbstractCanvasObject holonObject)
-    {
-    	return (holonObject.equals(a) || holonObject.equals(b));
+    public boolean isConnectedTo(AbstractCanvasObject holonObject) {
+        return (holonObject.equals(a) || holonObject.equals(b));
     }
+
     @Override
-    public String toString(){
-    	String A = (a == null) ? "null" : a.getName() + "[" + a.getId()+ "]";
-    	String B = (b == null) ? "null" : b.getName() + "[" + b.getId()+ "]";
-    	return "CpsEdge: " + A + " to " + B;
-    }
-
-	public boolean isBreakedManuel() {
-		return breakedManuel;
-	}
-
-	public void setBreakedManuel(boolean breakedManuel) {
-		this.breakedManuel = breakedManuel;
-	}
-
-	public boolean isUnlimitedCapacity() {
-		return unlimitedCapacity;
-	}
-
-	public void setUnlimitedCapacity(boolean unlimitedCapacity) {
-		this.unlimitedCapacity = unlimitedCapacity;
-	}
-
-	/*
-	 * STATE 
-	 */
-	public enum EdgeState{
-		Working, Burned
-	}
-	private EdgeState state = initState();
-	private float flowEnergy = 0;
-	
-	public EdgeState getState() {
-		return state;
-	}
-	//TODO(Tom 2021-12-3): public -> package
-	public void reset() {
-		state = initState();
-	}
-	private EdgeState initState() {
-		if (breakedManuel) {
-			return EdgeState.Burned;
-		}else {
-			return EdgeState.Working;
-		}
-	}
-	
-	public float getActualFlow() {
-		return flowEnergy;
-	}
-	
-	
-	public float getEnergyFromConneted() {
-		float energy = 0.0f;
-		if(getA() instanceof HolonObject hO && hO.getActualEnergy() > 0) {
-			energy += hO.getActualEnergy();
-		}
-		if(getB() instanceof HolonObject hO && hO.getActualEnergy() > 0) {
-			energy += hO.getActualEnergy();
-		}
-		return energy;
-	}
-
-	//TODO(Tom 2021-12-3): public -> package
-	public void setActualFlow(float energyToSupplyInTheNetwork) {
-		flowEnergy = energyToSupplyInTheNetwork;
-	}
-	//TODO(Tom 2021-12-3): public -> package
-	public void setState(EdgeState state) {
-		this.state = state;
-	}
+    public String toString() {
+        String A = (a == null) ? "null" : a.getName() + "[" + a.getId() + "]";
+        String B = (b == null) ? "null" : b.getName() + "[" + b.getId() + "]";
+        return "CpsEdge: " + A + " to " + B;
+    }
+
+    public EdgeState getState() {
+        return state;
+    }
+
+    //TODO(Tom 2021-12-3): public -> package
+    public void setState(EdgeState state) {
+        this.state = state;
+    }
+
+    //TODO(Tom 2021-12-3): public -> package
+    public void reset() {
+        state = initState();
+    }
+
+    private EdgeState initState() {
+        if (mode == EdgeMode.Disconnected) {
+            return EdgeState.Burned;
+        }
+        return EdgeState.Working;
+    }
+
+    public float getActualFlow() {
+        return flowEnergy;
+    }
+
+    //TODO(Tom 2021-12-3): public -> package
+    public void setActualFlow(float energyToSupplyInTheNetwork) {
+        flowEnergy = energyToSupplyInTheNetwork;
+    }
+
+    public float getEnergyFromConneted() {
+        float energy = 0.0f;
+        if (getA() instanceof HolonObject hO && hO.getActualEnergy() > 0) {
+            energy += hO.getActualEnergy();
+        }
+        if (getB() instanceof HolonObject hO && hO.getActualEnergy() > 0) {
+            energy += hO.getActualEnergy();
+        }
+        return energy;
+    }
+
+    public enum EdgeMode {
+        Normal, Unlimited, Disconnected
+    }
+
+    /*
+     * STATE
+     */
+    public enum EdgeState {
+        Working, Burned
+    }
 }

+ 174 - 0
src/holeg/model/Holon.java

@@ -0,0 +1,174 @@
+package holeg.model;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+public class Holon {
+    private static final Logger log = Logger.getLogger(Holon.class.getName());
+    public Set<HolonObject> holonObjects = new HashSet<>();
+    public Set<AbstractCanvasObject> objects = new HashSet<>();
+    public Set<Edge> edges = new HashSet<>();
+
+    public Holon(HolonObject holonObject) {
+        holonObjects.add(holonObject);
+        objects.add(holonObject);
+    }
+
+    public Holon(Edge edge) {
+        add(edge);
+    }
+
+    public void add(Edge edge) {
+        add(edge.getA());
+        add(edge.getB());
+        edges.add(edge);
+    }
+
+    public void add(AbstractCanvasObject obj) {
+        if (obj instanceof HolonObject holonObject) {
+            holonObjects.add(holonObject);
+        }
+        objects.add(obj);
+    }
+
+
+    public void merge(Holon other) {
+        holonObjects.addAll(other.holonObjects);
+        edges.addAll(other.edges);
+        objects.addAll(other.objects);
+        other.clear();
+    }
+
+    public void clear() {
+        holonObjects.clear();
+        edges.clear();
+        objects.clear();
+    }
+
+    @Override
+    public String toString() {
+        return "[" + objects.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]";
+    }
+
+
+    public void calculate(int timeStep) {
+        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()
+        );
+
+        float energyToSupplyInTheNetwork = supplierList.stream()
+                .map(HolonObject::getActualEnergy)
+                .reduce(0f, Float::sum);
+
+
+        // STEP 1:
+        // Supply consuming element first
+
+        // Sort ConsumerList according to the MinimumConsumingElementEnergy minimum first.
+        consumerList.sort((a, b) -> Float.compare(a.getMinimumConsumingElementEnergy(), b.getMinimumConsumingElementEnergy()));
+        outerLoop:
+        for (HolonObject con : consumerList) {
+            for (HolonObject sup : supplierList) {
+                float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
+                if (energyRdyToSupply <= 0.0f) {
+                    continue;
+                }
+                float energyNeededForMinimumConsumingElement = con.getMinimumConsumingElementEnergy()
+                        - con.getEnergyFromHolon();
+                if (energyNeededForMinimumConsumingElement > energyToSupplyInTheNetwork) {
+                    // Dont supply a minimumElement when you cant supply it fully
+                    break outerLoop;
+                }
+                if (energyRdyToSupply >= energyNeededForMinimumConsumingElement) {
+                    energyToSupplyInTheNetwork -= energyNeededForMinimumConsumingElement;
+                    supply(con, sup, energyNeededForMinimumConsumingElement);
+                    continue outerLoop;
+                } else {
+                    energyToSupplyInTheNetwork -= energyRdyToSupply;
+                    supply(con, sup, energyRdyToSupply);
+                }
+            }
+            // No more Energy in the network
+            break;
+        }
+
+        log.info("Supplier [" + supplierList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
+                "Consumer [" + consumerList.stream().map(hO -> hO.getName() + hO.getActualEnergy()).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
+        );
+
+
+        // STEP 2:
+        // Supply consumer fully
+
+        // Sort ConsumerList according to the EnergyNeeded to supply fully after minimum
+        // Demand First.
+        consumerList.sort((l, r) -> Float.compare(
+                l.getEnergyNeededFromHolon() - l.getEnergyFromHolon(),
+                r.getEnergyNeededFromHolon() - r.getEnergyFromHolon()));
+        outerLoop:
+        for (HolonObject con : consumerList) {
+            for (HolonObject sup : supplierList) {
+                float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
+                if (energyRdyToSupply <= 0.0f)
+                    continue;
+                float energyNeededForFullySupply = con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
+                if (energyNeededForFullySupply <= 0.0f)
+                    continue outerLoop;
+                if (energyRdyToSupply >= energyNeededForFullySupply) {
+                    energyToSupplyInTheNetwork -= energyNeededForFullySupply;
+                    supply(con, sup, energyNeededForFullySupply);
+                    continue outerLoop;
+                } else {
+                    energyToSupplyInTheNetwork -= energyRdyToSupply;
+                    supply(con, sup, energyRdyToSupply);
+                }
+            }
+            // No more Energy in the network
+            break;
+        }
+
+        log.info("energyToSupplyInTheNetwork: " + energyToSupplyInTheNetwork);
+        if (energyToSupplyInTheNetwork > 0.0f && (consumerList.size() != 0)) {
+            float equalAmountOfEnergyToSupply = energyToSupplyInTheNetwork
+                    / ((float) (consumerList.size()));
+            outerLoop:
+            for (HolonObject con : consumerList) {
+                for (HolonObject sup : supplierList) {
+                    float energyRdyToSupply = sup.getActualEnergy() - sup.getEnergyToHolon();
+                    if (energyRdyToSupply <= 0.0f)
+                        continue;
+                    float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply
+                            + con.getEnergyNeededFromHolon() - con.getEnergyFromHolon();
+                    if (energyRdyToSupply >= energyNeededToSupplyConsumerTheEqualAmount) {
+                        supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
+                        continue outerLoop;
+                    } else {
+                        supply(con, sup, energyRdyToSupply);
+                    }
+                }
+                // No more Energy in the network
+                break;
+            }
+        }
+        holonObjects.forEach(HolonObject::calculateState);
+    }
+
+
+    private void supply(HolonObject consumer, HolonObject supplier, float energy) {
+        consumer.setEnergyFromHolon(consumer.getEnergyFromHolon() + energy);
+        supplier.setEnergyToHolon(supplier.getEnergyToHolon() + energy);
+    }
+}

+ 258 - 299
src/holeg/model/HolonObject.java

@@ -3,6 +3,7 @@ package holeg.model;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -14,303 +15,261 @@ import java.util.stream.Stream;
  * @author Gruppe14
  */
 public class HolonObject extends AbstractCanvasObject {
-	/* Array of all consumers */
-	private List<HolonElement> elements = new ArrayList<HolonElement>();
-
-	/**
-	 * Constructor Set by default the name of the object equals to the category
-	 * name, until the user changes it.
-	 *
-	 * @param objName name of the Object
-	 */
-	public HolonObject(String objName) {
-		super(objName);
-	}
-
-	/**
-	 * Contructor of a copy of an Object.
-	 *
-	 * @param obj object to be copied
-	 */
-	public HolonObject(HolonObject obj) {
-		super(obj);
-		for (HolonElement ele : obj.elements) {
-			this.add(new HolonElement(ele));
-		}
-	}
-
-	@Override
-	public void initForReflection() {
-		elements = new ArrayList<HolonElement>();
-	}
-
-	/**
-	 * Getter for all Elements in the HolonObject.
-	 *
-	 * @return the elements ArrayList
-	 */
-	public Stream<HolonElement> getElements() {
-		return elements.stream();
-	}
-
-	public void clearElements() {
-		elements.clear();
-	}
-
-	/**
-	 * adds an Element to the Object.
-	 *
-	 * @param element the Element to add
-	 */
-	public void add(HolonElement element) {
-		elements.add(element);
-		element.parentObject = this;
-	}
-
-	/**
-	 * adds an Element to the Object.
-	 *
-	 * @param element the Element to add
-	 */
-	public void add(Collection<HolonElement> elements) {
-		for (HolonElement hE : elements) {
-			hE.parentObject = this;
-		}
-		this.elements.addAll(elements);
-	}
-
-	/**
-	 * remove an Element to the Object.
-	 *
-	 * @param element the Element to add
-	 */
-	public void remove(HolonElement element) {
-		elements.remove(element);
-		element.parentObject = null;
-	}
-
-	public void removeElement(int index) {
-		HolonElement ele = elements.remove(index);
-		ele.parentObject = null;
-	}
-
-	/**
-	 * This Method returns the smallest consuming HolonElement that is ACTIVE. If
-	 * the HolonObject has no Consumer its return null.
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The smallest consuming HolonElement or null.
-	 */
-	public HolonElement getMinimumConsumingElement() {
-		return elements.stream().filter(element -> element.getActualEnergy() < 0)
-				.max((lhs, rhs) -> Float.compare(lhs.getActualEnergy(), rhs.getActualEnergy())).orElse(null);
-	}
-
-	/**
-	 * This Method returns the smallest consuming HolonElement'Energy that is
-	 * ACTIVE. If the HolonObject has no Consumer its return 0.
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The smallest consuming HolonElement or 0.
-	 */
-	public float getMinimumConsumingElementEnergy() {
-		return elements.stream().filter(element -> element.getActualEnergy() < 0)
-				.map(element -> -element.getActualEnergy()).min((lhs, rhs) -> Float.compare(lhs, rhs)).orElse(0.0f);
-	}
-
-	/**
-	 * This Method returns the biggest consuming HolonElement'Energy that is ACTIVE.
-	 * If the HolonObject has no Consumer its return 0.
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The biggest consuming HolonElement or 0.
-	 */
-	public float getMaximumConsumingElementEnergy() {
-		return elements.stream().filter(element -> element.getActualEnergy() < 0)
-				.map(element -> -element.getActualEnergy()).max((lhs, rhs) -> Float.compare(lhs, rhs)).orElse(0.0f);
-	}
-
-	public float getMaximumProductionPossible() {
-		return elements.stream().filter(element -> element.getEnergy() > 0).map(element -> element.getEnergy())
-				.reduce(0.0f, Float::sum);
-	}
-
-	public float getMaximumConsumptionPossible() {
-		return elements.stream().filter(element -> element.getEnergy() < 0).map(element -> -element.getEnergy())
-				.reduce(0.0f, Float::sum);
-	}
-
-	/**
-	 * This Method returns the Energy that all HolonElements from the HolonObject
-	 * produce by itself. Its sums all Energies from the HolonElements of the
-	 * HolonObject that are ACTIVE and are Producer. If the HolonObject have no
-	 * HolonElement its return 0;
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The Energy of the producing HolonElements.
-	 */
-	public float getEnergySelfProducingFromProducingElements() {
-		return elements.stream().filter(element -> element.getActualEnergy() > 0)
-				.map(element -> element.getActualEnergy()).reduce(0.0f, Float::sum);
-	}
-
-	/**
-	 * This Method returns the Energy of all HolonElements from the HolonObject that
-	 * are consuming. Its sums all Energies from the HolonElements of the
-	 * HolonObject that are ACTIVE and are Consumer. If the HolonObject have no
-	 * HolonElement its return 0;
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The Energy of the consuming HolonElements.
-	 */
-	public float getEnergyNeededFromConsumingElements() {
-		return elements.stream().filter(element -> element.getActualEnergy() < 0)
-				.map(element -> -element.getActualEnergy()).reduce(0.0f, Float::sum);
-	}
-
-	/**
-	 * This Method calculate the amount of HolonElements that are consuming Energy
-	 * and are ACTIVE.
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The amount of HolonElements that are consuming Energy.
-	 */
-	public int countConsumingElements() {
-		return (int) elements.stream().filter(element -> element.getActualEnergy() < 0).count();
-	}
-
-	/**
-	 * This Method calculate the amount of HolonElements that are producing Energy
-	 * and are ACTIVE.
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The amount of HolonElements that are producing Energy.
-	 */
-	public int countProducingElements() {
-		return (int) elements.stream().filter(element -> element.getActualEnergy() > 0).count();
-	}
-
-	public int getNumberOfActiveElements() {
-		return (int) elements.stream().filter(ele -> ele.active).count();
-	}
-
-	public int getNumberOfInActiveElements() {
-		return (int) elements.stream().filter(ele -> !ele.active).count();
-	}
-
-	public int getNumberOfElements() {
-		return elements.size();
-	}
-
-	/*
-	 * STATE
-	 */
-	private float actualEnergy;
-	private HolonObjectState state;
-	private float energyFromNetwork;
-	private float minimumConsumingElementEnergy;
-	private float energyNeededFromNetwork;
-	private float energyFromConsumingElemnets;
-	private float energySelfSupplied;
-
-	/**
-	 * This Method returns the Energy of a HolonObject. Its sums all Energies from
-	 * the HolonElements of the HolonObject that are ACTIVE. If the HolonObject have
-	 * no HolonElement its return 0; Is the returned Energy negative then the
-	 * HolonObject need Energy because its consuming HolonElements need more Energy
-	 * then the producing HolonElements. Is the returned Energy positive its
-	 * reversed.
-	 * 
-	 * @param timestep is the TimeStep to compare the HolonElements.
-	 * @return The Energy of the HolonObject.
-	 */
-	public void calculateEnergy(int timestep) {
-		elements.forEach(ele -> ele.calculateState(timestep));
-		actualEnergy = elements.stream().map(element -> element.getActualEnergy()).reduce(0.0f, Float::sum);
-	}
-
-	public float getActualEnergy() {
-		return actualEnergy;
-	}
-
-	public enum HolonObjectState {
-		NO_ENERGY, NOT_SUPPLIED, SUPPLIED, PRODUCER, PARTIALLY_SUPPLIED, OVER_SUPPLIED
-	}
-
-	public HolonObjectState getState() {
-		return state;
-	}
-
-	public void setState(HolonObjectState state) {
-		this.state = state;
-	}
-
-	public float getEnergyFromNetwork() {
-		return energyFromNetwork;
-	}
-
-	// TODO(Tom2021-01-11): Should not exist hidden or package visibility
-	public void setEnergyFromNetwork(float energyFromNetwork) {
-		this.energyFromNetwork = energyFromNetwork;
-	}
-
-	public float getMinimumConsumingElementEnergyState() {
-		return minimumConsumingElementEnergy;
-	}
-
-	// TODO(Tom2021-01-11): Should not exist hidden or package visibility
-	public void setMinimumConsumingElementEnergy(float minimumConsumingElementEnergy) {
-		this.minimumConsumingElementEnergy = minimumConsumingElementEnergy;
-	}
-
-	public float getEnergyNeededFromNetwork() {
-		return energyNeededFromNetwork;
-	}
-
-	// TODO(Tom2021-01-11): Should not exist hidden or package visibility
-	public void setEnergyNeededFromNetwork(float energyNeededFromNetwork) {
-		this.energyNeededFromNetwork = energyNeededFromNetwork;
-	}
-
-	public float getEnergyFromConsumingElemnets() {
-		return energyFromConsumingElemnets;
-	}
-
-	// TODO(Tom2021-01-11): Should not exist hidden or package visibility
-	public void setEnergyFromConsumingElemnets(float energyFromConsumingElemnets) {
-		this.energyFromConsumingElemnets = energyFromConsumingElemnets;
-	}
-
-	public float getEnergySelfSupplied() {
-		return energySelfSupplied;
-	}
-
-	// TODO(Tom2021-01-11): Should not exist hidden or package visibility
-	public void setEnergySelfSupplied(float energySelfSupplied) {
-		this.energySelfSupplied = energySelfSupplied;
-	}
-
-	float getCurrentEnergy() {
-		return energyFromNetwork-energyNeededFromNetwork;
-	}	
-
-	
-	public float getSupplyBarPercentage() {
-		return (getEnergyFromConsumingElemnets() > 0.001)
-				? (getEnergyFromNetwork() + this.getEnergySelfSupplied()) / getEnergyFromConsumingElemnets()
-				: 1.0f;
-	}
-
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		sb.append("[HolonObject: ").append("id=").append(getId()).append(", name=").append(name).append(", state=")
-				.append(state).append(", elements=[")
-				.append(getElements().map(HolonElement::getName).collect(Collectors.joining(", "))).append("]]");
-		return sb.toString();
-	}
-
-	
-	
-	
-	
+    /* Array of all consumers */
+    private List<HolonElement> elements = new ArrayList<>();
+
+    //Calculated values
+    private HolonObjectState state;
+    private float actualEnergy;
+    private float energyFromHolon;
+    private float energyToHolon;
+    private float minimumConsumingElementEnergy;
+    private float energyNeededFromHolon;
+    private float energyFromConsumingElements;
+    private float energySelfSupplied;
+
+    /**
+     * Constructor Set by default the name of the object equals to the category
+     * name, until the user changes it.
+     *
+     * @param objName name of the Object
+     */
+    public HolonObject(String objName) {
+        super(objName);
+    }
+
+    /**
+     * Contructor of a copy of an Object.
+     *
+     * @param obj object to be copied
+     */
+    public HolonObject(HolonObject obj) {
+        super(obj);
+        for (HolonElement ele : obj.elements) {
+            this.add(new HolonElement(ele));
+        }
+    }
+
+    @Override
+    public void initForReflection() {
+        elements = new ArrayList<HolonElement>();
+    }
+
+    /**
+     * Getter for all Elements in the HolonObject.
+     *
+     * @return the elements ArrayList
+     */
+    public Stream<HolonElement> getElements() {
+        return elements.stream();
+    }
+
+    public void clearElements() {
+        elements.clear();
+    }
+
+    /**
+     * adds an Element to the Object.
+     *
+     * @param element the Element to add
+     */
+    public void add(HolonElement element) {
+        elements.add(element);
+        element.parentObject = this;
+    }
+
+    public void add(Collection<HolonElement> elements) {
+        for (HolonElement hE : elements) {
+            hE.parentObject = this;
+        }
+        this.elements.addAll(elements);
+    }
+
+    /**
+     * remove an Element to the Object.
+     *
+     * @param element the Element to add
+     */
+    public void remove(HolonElement element) {
+        elements.remove(element);
+        element.parentObject = null;
+    }
+
+    public void removeElement(int index) {
+        HolonElement ele = elements.remove(index);
+        ele.parentObject = null;
+    }
+
+    /**
+     * This Method returns the smallest consuming HolonElement that is ACTIVE. If
+     * the HolonObject has no Consumer its return null.
+     *
+     * @return The smallest consuming HolonElement or null.
+     */
+    public Optional<HolonElement> getMinimumConsumingElement() {
+        return elements.stream().filter(element -> element.getActualEnergy() < 0).max((lhs, rhs) -> Float.compare(lhs.getActualEnergy(), rhs.getActualEnergy()));
+    }
+
+    /**
+     * This Method returns the smallest consuming HolonElement'Energy that is
+     * ACTIVE. If the HolonObject has no Consumer its return 0.
+     *
+     * @return The smallest consuming HolonElement or 0.
+     */
+    public float getMinimumConsumingElementEnergy() {
+        return minimumConsumingElementEnergy;
+    }
+
+    /**
+     * This Method returns the biggest consuming HolonElement'Energy that is ACTIVE.
+     * If the HolonObject has no Consumer its return 0.
+     *
+     * @return The biggest consuming HolonElement or 0.
+     */
+    public float getMaximumConsumingElementEnergy() {
+        return elements.stream().filter(element -> element.getActualEnergy() < 0).map(element -> -element.getActualEnergy()).max(Float::compare).orElse(0.0f);
+    }
+
+    public float getMaximumProductionPossible() {
+        return elements.stream().map(HolonElement::getEnergy).filter(energy -> energy > 0).reduce(0.0f, Float::sum);
+    }
+
+    public float getMaximumConsumptionPossible() {
+        return elements.stream().filter(element -> element.getEnergy() < 0).map(element -> -element.getEnergy()).reduce(0.0f, Float::sum);
+    }
+
+    /**
+     * This Method returns the Energy of all HolonElements from the HolonObject that
+     * are consuming. Its sums all Energies from the HolonElements of the
+     * HolonObject that are ACTIVE and are Consumer. If the HolonObject have no
+     * HolonElement its return 0;
+     *
+     * @return The Energy of the consuming HolonElements.
+     */
+    public float getEnergyNeededFromConsumingElements() {
+        return energyFromConsumingElements;
+    }
+
+    /**
+     * This Method calculate the amount of HolonElements that are consuming Energy
+     * and are ACTIVE.
+     *
+     * @return The amount of HolonElements that are consuming Energy.
+     */
+    public int countConsumingElements() {
+        return (int) elements.stream().filter(element -> element.getActualEnergy() < 0).count();
+    }
+
+    /**
+     * This Method calculate the amount of HolonElements that are producing Energy
+     * and are ACTIVE.
+     *
+     * @return The amount of HolonElements that are producing Energy.
+     */
+    public int countProducingElements() {
+        return (int) elements.stream().filter(element -> element.getActualEnergy() > 0).count();
+    }
+
+    public int getNumberOfActiveElements() {
+        return (int) elements.stream().filter(ele -> ele.active).count();
+    }
+
+    public int getNumberOfInActiveElements() {
+        return (int) elements.stream().filter(ele -> !ele.active).count();
+    }
+
+    public int getNumberOfElements() {
+        return elements.size();
+    }
+
+    /**
+     * This Method returns the Energy of a HolonObject. Its sums all Energies from
+     * the HolonElements of the HolonObject that are ACTIVE. If the HolonObject have
+     * no HolonElement its return 0; Is the returned Energy negative then the
+     * HolonObject need Energy because its consuming HolonElements need more Energy
+     * then the producing HolonElements. Is the returned Energy positive its
+     * reversed.
+     *
+     * @param timeStep is the TimeStep to compare the HolonElements.
+     */
+    public void calculateEnergy(int timeStep) {
+        elements.forEach(ele -> ele.calculateState(timeStep));
+        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);
+        energyToHolon = energyFromHolon = 0;
+    }
+
+    public float getActualEnergy() {
+        return actualEnergy;
+    }
+
+    public HolonObjectState getState() {
+        return state;
+    }
+
+    void setState(HolonObjectState state) {
+        this.state = state;
+    }
+
+    public float getEnergyFromHolon() {
+        return energyFromHolon;
+    }
+
+    void setEnergyFromHolon(float energyFromHolon) {
+        this.energyFromHolon = energyFromHolon;
+    }
+
+    public float getEnergyNeededFromHolon() {
+        return energyNeededFromHolon;
+    }
+
+
+    public float getEnergySelfSupplied() {
+        return energySelfSupplied;
+    }
+
+    public float getCurrentEnergy() {
+        return energyFromHolon - energyNeededFromHolon;
+    }
+
+    public float getSupplyBarPercentage() {
+        return (energyFromConsumingElements > 0.001) ? (energyFromHolon + energySelfSupplied) / energyFromConsumingElements : 1.0f;
+    }
+
+    public String toString() {
+        return "[HolonObject: " + "id=" + getId() + ", name=" + name + ", state=" + state + ", elements=[" + getElements().map(HolonElement::getName).collect(Collectors.joining(", ")) + "]]";
+    }
+
+    public float getEnergyToHolon() {
+        return energyToHolon;
+    }
+
+    void setEnergyToHolon(float energyToHolon) {
+        this.energyToHolon = energyToHolon;
+    }
+
+    public void calculateState() {
+        if(actualEnergy > 0){
+            state = HolonObjectState.PRODUCER;
+        }else if(elements.isEmpty()){
+            state = HolonObjectState.NO_ENERGY;
+        }else if(energySelfSupplied + energyFromHolon > energyFromConsumingElements) {
+            state = (HolonObjectState.OVER_SUPPLIED);
+        }else if(energySelfSupplied + energyFromHolon == energyFromConsumingElements) {
+            state = (HolonObjectState.SUPPLIED);
+        }else if(energySelfSupplied + energyFromHolon >= minimumConsumingElementEnergy) {
+            state = (HolonObjectState.PARTIALLY_SUPPLIED);
+        }else {
+            state = (HolonObjectState.NOT_SUPPLIED);
+        }
+    }
+
+    public enum HolonObjectState {
+        NO_ENERGY, NOT_SUPPLIED, SUPPLIED, PRODUCER, PARTIALLY_SUPPLIED, OVER_SUPPLIED
+    }
+
+
 }

+ 19 - 32
src/holeg/preferences/ColorPreference.java

@@ -25,29 +25,22 @@ public class ColorPreference {
 		public static final Color Inactive = new Color(128, 154, 163);
 	}
 	public static class HolonObject{
-		public static final Color Producer = new Color(153, 204, 255);
+		public static final Color Producer = new Color(149, 152, 159, 211);
 		public static final Color OverSupplied = new Color(166, 78, 229);
 		public static final Color Supplied = new Color(13, 175, 28);
-		public static final Color PartiallySupplied = Color.yellow;
+		public static final Color PartiallySupplied = new Color(255, 233, 1);
 		public static final Color NotSupplied = new Color(230, 120, 100);
-		public static final Color NoEnergy = Color.white;
+		public static final Color NoEnergy = new Color(211, 211, 211);
 	
 		public static Color getStateColor(HolonObjectState state) {
-			switch (state) {
-			case NOT_SUPPLIED:
-				return NotSupplied;
-			case OVER_SUPPLIED:
-				return OverSupplied;
-			case PARTIALLY_SUPPLIED:
-				return PartiallySupplied;
-			case PRODUCER:
-				return Producer;
-			case SUPPLIED:
-				return Supplied;
-			case NO_ENERGY:
-			default:
-				return NoEnergy;
-			}
+			return switch (state) {
+				case NOT_SUPPLIED -> NotSupplied;
+				case OVER_SUPPLIED -> OverSupplied;
+				case PARTIALLY_SUPPLIED -> PartiallySupplied;
+				case PRODUCER -> Producer;
+				case SUPPLIED -> Supplied;
+				case NO_ENERGY -> NoEnergy;
+			};
 		}
 	}
 	
@@ -70,19 +63,13 @@ public class ColorPreference {
 		public static final Color Unavailable = new Color(193, 193, 193);
 		
 		public static Color getStateColor(FlexState state) {
-			switch(state) {
-			case IN_USE:
-				return InUse;
-			case NOT_OFFERED:
-				return NotOffered;
-			case OFFERED:
-				return Offered;
-			case ON_COOLDOWN:
-				return OnCooldown;
-			case UNAVAILABLE:
-			default:
-				return Unavailable;
-			}
+			return switch (state) {
+				case IN_USE -> InUse;
+				case NOT_OFFERED -> NotOffered;
+				case OFFERED -> Offered;
+				case ON_COOLDOWN -> OnCooldown;
+				case UNAVAILABLE -> Unavailable;
+			};
 		}
 	}
 	
@@ -94,7 +81,7 @@ public class ColorPreference {
 	public static class Canvas {
 		public static final Color MouseSelectionBorder = new Color(0, 120, 215);
 		public static final Color MouseSelectionFill = new Color(128, 174, 247, 40);
-		public static final Color ObjectSelectionBorder = new Color(153, 209, 255);;
+		public static final Color ObjectSelectionBorder = new Color(153, 209, 255);
 		public static final Color ObjectSelectionFill = new Color(205, 233, 255);
 	}
 

+ 2 - 2
src/holeg/ui/controller/ClipboardController.java

@@ -135,7 +135,7 @@ public class ClipboardController {
         // for selecting Cps
         getObjectsInDepth();
         forwardEdges(edges, json, objDispatch, upperNode);
-        this.simManager.calculateStateForTimeStep(model.getCurrentIteration(), true);
+        this.simManager.calculateStateForTimeStep(model.getCurrentIteration());
     }
 
     /**
@@ -153,7 +153,7 @@ public class ClipboardController {
                 cvsC.deleteAllObjectsInGroupNode(groupnode);
         }
         GuiSettings.getSelectedObjects().clear();
-        this.simManager.calculateStateForTimeStep(model.getCurrentIteration(), true);
+        this.simManager.calculateStateForTimeStep(model.getCurrentIteration());
 
     }
 

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

@@ -196,12 +196,6 @@ public class Control {
 		saveCategory();
 	}
 
-	/**
-	 * delete a given Category.
-	 *
-	 * @param cat the Category
-	 * @throws IOException
-	 */
 	public void deleteCategory(Category category) {
 		categoryController.removeCategory(category);
 		saveCategory();
@@ -389,7 +383,7 @@ public class Control {
 	}
 
 	public void calculateStateOnlyForCurrentTimeStep() {
-		simulationManager.calculateStateForTimeStep(model.getCurrentIteration(), false);
+		simulationManager.calculateStateForTimeStep(model.getCurrentIteration());
 	}
 
 	/**
@@ -398,10 +392,8 @@ public class Control {
 	 * @param x current Iteration
 	 */
 	public void calculateStateAndVisualForTimeStep(int x) {
-		simulationManager.calculateStateForTimeStep(x, true);
+		simulationManager.calculateStateForTimeStep(x);
 		OnCanvasUpdate.broadcast();
-		// TODO(Tom2021-12-2): Convert to Events
-		this.updateCanvas();
 	}
 
 	/**
@@ -600,10 +592,6 @@ public class Control {
 	}
 
 
-	public void updateCanvas() {
-		log.info("updateCanvas");
-	}
-
 	public void guiSetEnabled(boolean state) {
 		log.info("guiDisabled");
 		OnGuiSetEnabled.broadcast(state);

+ 112 - 162
src/holeg/ui/controller/SimulationManager.java

@@ -1,178 +1,128 @@
 package holeg.ui.controller;
 
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.logging.Logger;
-
-import holeg.model.*;
+import holeg.model.AbstractCanvasObject;
+import holeg.model.Edge;
 import holeg.model.Edge.EdgeState;
+import holeg.model.HolonObject;
+import holeg.model.HolonSwitch;
 import holeg.model.HolonSwitch.SwitchState;
-import holeg.ui.model.MinimumModel;
-import holeg.ui.model.MinimumNetwork;
+import holeg.model.Holon;
 import holeg.ui.model.Model;
-import holeg.ui.model.Model.FairnessModel;
-
-/**
- * Controller for Simulation.
- *
- * @author Gruppe14
- */
-public class SimulationManager {
-	private static final Logger log = Logger.getLogger(SimulationManager.class.getName());
-	private Model model;
 
-	/**
-	 * Constructor.
-	 *
-	 * @param m Model
-	 */
-	public SimulationManager(Model m) {
-		log.fine("Construct SimulationManager");
-		model = m;
-	}
-
-	/**
-	 * calculates the flow of the edges and the supply for objects and consider old
-	 * timesteps for burned cables.
-	 *
-	 * @param timestep     current Iteration
-	 * @param updateVisual Determine if the Visuals should also be calculated
-	 */
-	public void calculateStateForTimeStep(int timestep, boolean updateVisual) {
-		log.fine("Calculate");
-		long start = System.currentTimeMillis();
-		ArrayList<MinimumNetwork> list = new ArrayList<>();
-		model.getCanvas().getAllSwitchObjectsRecursive().forEach(sw -> sw.calculateState(timestep));
-		MinimumModel minimumModel = new MinimumModel(model.getCanvas(), model.getEdgesOnCanvas(),
-				model.getCurrentIteration());
-		ArrayList<Edge> leftOver = new ArrayList<Edge>();
-
-		boolean doAnotherLoop = true;
-		do {
-			doAnotherLoop = false;
-			list = calculateNetworks(minimumModel, timestep, leftOver);
-			for (MinimumNetwork net : list) {
-				float energyOnCables = net.getHolonObjectList().stream().map(object -> object.getActualEnergy())
-						.filter(energy -> energy > 0.0f).reduce(0.0f, (Float::sum));
-				// find the cable with the energy supplied from his two connected objects are
-				// the biggest, from all cables that the network give more energy than the
-				// cablecapacity.
-				Edge cable = net.getEdgeList().stream()
-						.filter(aCable -> energyOnCables > aCable.maxCapacity && !aCable.isUnlimitedCapacity())
-						.max((lhs, rhs) -> Float.compare(lhs.getEnergyFromConneted(), rhs.getEnergyFromConneted()))
-						.orElse(null);
-				if (cable != null) {
-					cable.setState(EdgeState.Burned);
-					doAnotherLoop = true;
-				}
-			}
-		} while (doAnotherLoop);
-//		ArrayList<DecoratedNetwork> decorNetworks = new ArrayList<DecoratedNetwork>();
-//		FairnessModel actualFairnessModel = model.getFairnessModel();
-//		for (MinimumNetwork net : list) {
-//			decorNetworks.add(new DecoratedNetwork(net, timestep, actualFairnessModel));
-//		}
+import java.util.*;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
 
-		for (Edge cable : leftOver) {
-			cable.setActualFlow(0.0f);
-		}
-//		DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOver,
-//				timestep);
-//		actualDecorState = Optional.of(stateFromThisTimestep);
-		long end = System.currentTimeMillis();
-		log.finer("Simulation: " + (end - start) + "ms");
-	}
+public class SimulationManager {
+    private static final Logger log = Logger.getLogger(SimulationManager.class.getName());
+    private final Model model;
 
+    public SimulationManager(Model m) {
+        log.fine("Construct SimulationManager");
+        model = m;
+    }
 
-	/**
-	 * SubFunction to calculate the Networks from the model.
-	 * 
-	 * @param minModel
-	 * @param Iteration
-	 * @param leftOver
-	 * @return
-	 */
-	ArrayList<MinimumNetwork> calculateNetworks(MinimumModel minModel, int Iteration, ArrayList<Edge> leftOver) {
-		// Copy minModel ObjectList
-		ArrayList<HolonObject> holonObjectList = new ArrayList<HolonObject>();
-		for (HolonObject holonObject : minModel.getHolonObjectList()) {
-			holonObjectList.add(holonObject);
-		}
-		// Copy minModelEdgeList
-		ArrayList<Edge> edgeList = new ArrayList<Edge>();
-		for (Edge cable : minModel.getEdgeList()) {
-			edgeList.add(cable);
-		}
+    public void calculateStateForTimeStep(int timeStep) {
+        log.fine("Calculate");
+        long start = System.currentTimeMillis();
+        model.getCanvas().getAllSwitchObjectsRecursive().forEach(sw -> sw.calculateState(timeStep));
+        List<HolonObject> holonObjectList = model.getCanvas().getAllHolonObjectsRecursive().collect(Collectors.toList());
+        List<Edge> edgeList = new ArrayList<>(model.getEdgesOnCanvas());
+        Set<Holon> holons = getHolons(holonObjectList, edgeList, timeStep);
+        holons.forEach(holon -> holon.calculate(timeStep));
+        log.info("Holons:" + holons.stream().map(Object::toString).collect(Collectors.joining("\n")));
+        long end = System.currentTimeMillis();
+        log.finer("Simulation: " + (end - start) + "ms");
+    }
 
-		ArrayList<MinimumNetwork> listOfNetworks = new ArrayList<MinimumNetwork>();
-		while (!holonObjectList.isEmpty()) {
-			// lookAt the first holonObject and find his neighbors
-			HolonObject lookAtObject = holonObjectList.get(0);
-			// delete out of list
-			holonObjectList.remove(0);
-			// create a new Network
-			MinimumNetwork actualNetwork = new MinimumNetwork(new ArrayList<HolonObject>(), new ArrayList<Edge>());
-			actualNetwork.getHolonObjectList().add(lookAtObject);
-			// create List of neighbors
-			LinkedList<AbstractCanvasObject> neighbors = new LinkedList<AbstractCanvasObject>();
-			populateListOfNeighbors(edgeList, lookAtObject, actualNetwork, neighbors);
-			while (!neighbors.isEmpty()) {
-				AbstractCanvasObject lookAtNeighbor = neighbors.getFirst();
-				if (lookAtNeighbor instanceof HolonObject hO) {
-					actualNetwork.getHolonObjectList().add(hO);
-					holonObjectList.remove(lookAtNeighbor);
-				} else {
-					actualNetwork.getNodeAndSwitches().add(lookAtNeighbor);
-				}
-				// When HolonSwitch Check if closed
-				if (!(lookAtNeighbor instanceof HolonSwitch sw) || sw.getState() == SwitchState.Closed) {
-					populateListOfNeighbors(edgeList, lookAtNeighbor, actualNetwork, neighbors);
-				}
 
-				neighbors.removeFirst();
-			}
-			listOfNetworks.add(actualNetwork);
-		}
-		if (leftOver != null) {
-			leftOver.clear();
-			for (Edge cable : edgeList) {
-				leftOver.add(cable);
-			}
-		}
-		return listOfNetworks;
-	}
+    private Set<Holon> getHolons(List<HolonObject> holonObjectList, List<Edge> edgeList, int timeStep) {
+        log.info(System.lineSeparator() + "Supplier [" + holonObjectList.stream().map(AbstractCanvasObject::getName).collect(Collectors.joining(", ")) + "]" + System.lineSeparator() +
+                "Consumer [" + edgeList.stream().map(Object::toString).collect(Collectors.joining(", ")) + "]" + System.lineSeparator()
+        );
+        Set<Holon> holons = new HashSet<>();
+        for (Holon holon : calculateHolonStructure(holonObjectList, edgeList)) {
+            final float energyOnCables = holon.holonObjects.stream().map(hO -> {
+                        hO.calculateEnergy(timeStep);
+                        return hO.getActualEnergy();
+                    })
+                    .filter(energy -> energy > 0.0f).reduce(0.0f, (Float::sum));
+            // find the edge with the energy supplied from his two connected objects are
+            // the biggest, from all cables that the network give more energy than the
+            // edge capacity.
+            Optional<Edge> edge = holon.edges.stream()
+                    .filter(e -> energyOnCables > e.maxCapacity && e.mode == Edge.EdgeMode.Normal)
+                    .max((lhs, rhs) -> Float.compare(lhs.getEnergyFromConneted(), rhs.getEnergyFromConneted()));
+            edge.ifPresentOrElse(e -> {
+                //Burn Cable
+                e.setState(EdgeState.Burned);
+                e.setActualFlow(0.0f);
+                //Split Holon
+                holons.addAll(getHolons(new ArrayList<>(holon.holonObjects), new ArrayList<>(holon.edges), timeStep));
+            }, () -> {
+                holon.edges.forEach(e -> e.setActualFlow(energyOnCables));
+                holons.add(holon);
+            });
+        }
+        return holons;
+    }
 
-	/**
-	 * Adds the neighbors.
-	 * 
-	 * @param edgeList
-	 * @param lookAtObject
-	 * @param actualNetwork
-	 * @param neighbors
-	 */
-	void populateListOfNeighbors(ArrayList<Edge> edgeList, AbstractCanvasObject lookAtObject,
-			MinimumNetwork actualNetwork, LinkedList<AbstractCanvasObject> neighbors) {
-		ListIterator<Edge> iter = edgeList.listIterator();
-		while (iter.hasNext()) {
-			Edge lookAtEdge = iter.next();
-			if (lookAtEdge.getState() == EdgeState.Working && lookAtEdge.isConnectedTo(lookAtObject)) {
-				iter.remove();
-				actualNetwork.getEdgeList().add(lookAtEdge);
+    Set<Holon> calculateHolonStructure(List<HolonObject> holonObjectList, List<Edge> edgeList) {
+        Set<Holon> holons = new HashSet<>();
+        while (!holonObjectList.isEmpty()) {
+            // lookAt the first holonObject and find his neighbors
+            HolonObject lookAtObject = holonObjectList.get(0);
+            // delete out of list
+            holonObjectList.remove(0);
+            // create a new Network
+            Holon actualNetwork = new Holon(lookAtObject);
+            // create List of neighbors
+            LinkedList<AbstractCanvasObject> neighbors = new LinkedList<>();
+            populateListOfNeighbors(edgeList, lookAtObject, actualNetwork, neighbors);
+            while (!neighbors.isEmpty()) {
+                AbstractCanvasObject lookAtNeighbor = neighbors.getFirst();
+                if (lookAtNeighbor instanceof HolonObject) {
+                    holonObjectList.remove(lookAtNeighbor);
+                }
+                actualNetwork.add(lookAtNeighbor);
+                // When HolonSwitch Check if closed
+                if (!(lookAtNeighbor instanceof HolonSwitch sw) || sw.getState() == SwitchState.Closed) {
+                    populateListOfNeighbors(edgeList, lookAtNeighbor, actualNetwork, neighbors);
+                }
+                neighbors.removeFirst();
+            }
+            holons.add(actualNetwork);
+        }
+        for (Edge e : edgeList) {
+            e.setActualFlow(0.0f);
+        }
+        return holons;
+    }
 
-				// Add neighbar
-				AbstractCanvasObject edgeNeighbor;
-				if (lookAtEdge.getA().equals(lookAtObject)) {
-					edgeNeighbor = lookAtEdge.getB();
+    /**
+     * Adds  neighbors.
+     */
+    void populateListOfNeighbors(List<Edge> edgeList, AbstractCanvasObject lookAtObject,
+                                 Holon actualNetwork, LinkedList<AbstractCanvasObject> neighbors) {
+        ListIterator<Edge> iter = edgeList.listIterator();
+        while (iter.hasNext()) {
+            Edge lookAtEdge = iter.next();
+            if (lookAtEdge.getState() == EdgeState.Working && lookAtEdge.isConnectedTo(lookAtObject)) {
+                iter.remove();
+                actualNetwork.edges.add(lookAtEdge);
 
-				} else {
-					edgeNeighbor = lookAtEdge.getA();
-				}
-				if (!neighbors.contains(edgeNeighbor)) {
-					neighbors.add(edgeNeighbor);
-				}
-			}
-		}
-	}
+                // Add neighbor
+                AbstractCanvasObject edgeNeighbor;
+                if (lookAtEdge.getA().equals(lookAtObject)) {
+                    edgeNeighbor = lookAtEdge.getB();
+                } else {
+                    edgeNeighbor = lookAtEdge.getA();
+                }
+                if (!neighbors.contains(edgeNeighbor)) {
+                    neighbors.add(edgeNeighbor);
+                }
+            }
+        }
+    }
 
 }

+ 0 - 470
src/holeg/ui/model/DecoratedNetwork.java.orig

@@ -1,470 +0,0 @@
-package holeg.ui.model;
-
-import java.util.ArrayList;
-import java.util.stream.Stream;
-
-import holeg.model.Edge;
-import holeg.model.HolonElement;
-import holeg.model.HolonObject;
-import holeg.model.HolonObject.HolonObjectState;
-import holeg.ui.model.Model.FairnessModel;
-public class DecoratedNetwork {
-//	private ArrayList<Supplier> supplierList = new ArrayList<Supplier>();
-//	private ArrayList<Consumer> consumerList = new ArrayList<Consumer>();
-//	private ArrayList<Consumer> consumerSelfSuppliedList = new ArrayList<Consumer>();
-//	private ArrayList<Passiv> passivNoEnergyList = new ArrayList<Passiv>();
-	private ArrayList<Edge> edgeList = new ArrayList<Edge>();
-
-	public DecoratedNetwork(MinimumNetwork minimumNetwork, int Iteration, FairnessModel actualFairnessModel) {
-		switch (actualFairnessModel) {
-		case AllEqual:
-			calculateAllEqualNetwork(minimumNetwork, Iteration);
-			break;
-		case MininumDemandFirst:
-		default:
-			calculateMinimumDemandFirstNetwork(minimumNetwork, Iteration);
-			break;
-		}
-	}
-
-//	// Getter:
-//	public ArrayList<Supplier> getSupplierList() {
-//		return supplierList;
-//	}
-//
-//	public ArrayList<Consumer> getConsumerList() {
-//		return consumerList;
-//	}
-//
-//	public ArrayList<Consumer> getConsumerSelfSuppliedList() {
-//		return consumerSelfSuppliedList;
-//	}
-//
-//	public ArrayList<Passiv> getPassivNoEnergyList() {
-//		return passivNoEnergyList;
-//	}
-
-	public ArrayList<Edge> getDecoratedCableList() {
-		return edgeList;
-	}
-
-	// Calculations:
-	private void calculateMinimumDemandFirstNetwork(MinimumNetwork minimumNetwork, int Iteration) {
-		categorize(minimumNetwork, Iteration);
-		// Sort SupplierList according to the EnergyToSupplyNetwork maximum first.
-		// Sort ConsumerList according to the MinimumConsumingElementEnergy minimum
-		// first.
-		supplierList.sort((Supplier lhs,
-				Supplier rhs) -> -Float.compare(lhs.getEnergyToSupplyNetwork(), rhs.getEnergyToSupplyNetwork()));
-		consumerList.sort((Consumer lhs, Consumer rhs) -> Float.compare(lhs.getMinimumConsumingElementEnergy(),
-				rhs.getMinimumConsumingElementEnergy()));
-		// consumerList.forEach((con) ->
-		// System.out.println(con.getMinimumConsumingElementEnergy()));
-		// consumerList.forEach((con) -> System.out.println("AfterSorting" + con));
-		float energyToSupplyInTheNetwork = supplierList.stream()
-				.map(supplier -> supplier.getEnergyToSupplyNetwork() - supplier.getEnergySupplied())
-				.reduce(0.0f, (a, b) -> a + b);
-		decorateCable(minimumNetwork, energyToSupplyInTheNetwork);
-
-		outerLoop: for (Consumer con : consumerList) {
-			// gehe Supplier list durch wer ihn supplien kann.
-			for (Supplier sup : supplierList) {
-				float energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
-				if (energyRdyToSupply == 0.0f)
-					continue;
-				float energyNeededForMinimumConsumingElement = con.getMinimumConsumingElementEnergy()
-						- con.getEnergyFromNetwork();
-				if (energyNeededForMinimumConsumingElement > energyToSupplyInTheNetwork) {
-					// Dont supply a minimumElement when you cant supply it fully
-					break outerLoop;
-				}
-				if (energyRdyToSupply >= energyNeededForMinimumConsumingElement) {
-					energyToSupplyInTheNetwork -= energyNeededForMinimumConsumingElement;
-					supply(con, sup, energyNeededForMinimumConsumingElement);
-					continue outerLoop;
-				} else {
-					energyToSupplyInTheNetwork -= energyRdyToSupply;
-					supply(con, sup, energyRdyToSupply);
-				}
-			}
-			// No more Energy in the network
-			break;
-		}
-		// consumerList.forEach((con) -> System.out.println("AfterSuppliing
-		// MinimumDemand " + con));
-
-		// Sort ConsumerList according to the EnergyNeeded to supply fully after minimum
-		// Demand First.
-		consumerList.sort((Consumer lhs, Consumer rhs) -> Float.compare(
-				lhs.getEnergyNeededFromNetwork() - lhs.getEnergyFromNetwork(),
-				rhs.getEnergyNeededFromNetwork() - rhs.getEnergyFromNetwork()));
-		// Supply consumer fully
-		outerLoop: for (Consumer con : consumerList) {
-			// gehe Supplier list durch wer ihn supplien kann.
-			for (Supplier sup : supplierList) {
-				float energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
-				if (energyRdyToSupply == 0.0f)
-					continue;
-				float energyNeededForFullySupply = con.getEnergyNeededFromNetwork() - con.getEnergyFromNetwork();
-				if (energyNeededForFullySupply == 0.0f)
-					continue outerLoop;
-				if (energyRdyToSupply >= energyNeededForFullySupply) {
-					supply(con, sup, energyNeededForFullySupply);
-					continue outerLoop;
-				} else {
-					supply(con, sup, energyRdyToSupply);
-				}
-			}
-			// No more Energy in the network
-			break;
-		}
-		// consumerList.forEach((con) -> System.out.println("AfterFullySuplieing" +
-		// con));
-		// If Energy Left Supply all equal
-		// Count EnergyLeft
-		float energyLeft = supplierList.stream()
-				.map(supplier -> supplier.getEnergyToSupplyNetwork() - supplier.getEnergySupplied())
-				.reduce(0.0f, (a, b) -> a + b);
-		// System.out.println("EnergyLeft: " + energyLeft);
-		if (energyLeft > 0.0f && (consumerList.size() + consumerSelfSuppliedList.size() != 0)) {
-			float equalAmountOfEnergyToSupply = energyLeft
-					/ ((float) (consumerList.size() + consumerSelfSuppliedList.size()));
-			outerLoop: for (Consumer con : consumerList) {
-				// gehe Supplier list durch wer ihn supplien kann.
-				for (Supplier sup : supplierList) {
-					float energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
-					if (energyRdyToSupply == 0.0f)
-						continue;
-					float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply
-							+ con.getEnergyNeededFromNetwork() - con.getEnergyFromNetwork();
-					if (energyRdyToSupply >= energyNeededToSupplyConsumerTheEqualAmount) {
-						supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
-						continue outerLoop;
-					} else {
-						supply(con, sup, energyRdyToSupply);
-					}
-				}
-				// No more Energy in the network
-				break;
-			}
-			outerLoop: for (Consumer con : consumerSelfSuppliedList) {
-				// gehe Supplier list durch wer ihn supplien kann.
-				for (Supplier sup : supplierList) {
-					float energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
-					if (energyRdyToSupply == 0.0f)
-						continue;
-					float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply
-							+ con.getEnergyNeededFromNetwork() - con.getEnergyFromNetwork();
-					if (energyRdyToSupply >= energyNeededToSupplyConsumerTheEqualAmount) {
-						supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
-						continue outerLoop;
-					} else {
-						supply(con, sup, energyRdyToSupply);
-					}
-
-				}
-				// No more Energy in the network
-				break;
-			}
-		}
-		// consumerList.forEach((con) -> System.out.println("AfterOverSuppleiing" +
-		// con));
-
-		// consumerSelfSuppliedList.forEach((con) ->
-		// System.out.println("AfterOverSuppleiing" + con));
-
-		calculateStates();
-	}
-
-	private void decorateCable(MinimumNetwork minimumNetwork, float energyToSupplyInTheNetwork) {
-		// DecoratedCables
-		// Minimum demand first:
-		this.edgeList = minimumNetwork.getEdgeList();
-		for (Edge edge : edgeList) {
-			edge.setActualFlow(energyToSupplyInTheNetwork);
-		}
-	}
-
-	private void calculateAllEqualNetwork(MinimumNetwork minimumNetwork, int Iteration) {
-		categorize(minimumNetwork, Iteration);
-		float energyToSupplyInTheNetwork = supplierList.stream()
-				.map(supplier -> supplier.getEnergyToSupplyNetwork() - supplier.getEnergySupplied())
-				.reduce(0.0f, Float::sum);
-		float energyForEachConsumer = (consumerList.size() != 0) ? energyToSupplyInTheNetwork / consumerList.size()
-				: 0.0f;
-		decorateCable(minimumNetwork, energyToSupplyInTheNetwork);
-		// Supply consumer equal
-		outerLoop: for (Consumer con : consumerList) {
-			// gehe Supplier list durch wer ihn supplien kann.
-			float energyNeededForEqualSupply = energyForEachConsumer;
-			for (Supplier sup : supplierList) {
-				float energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
-				if (energyRdyToSupply == 0.0f)
-					continue;
-				if (energyRdyToSupply >= energyNeededForEqualSupply) {
-					supply(con, sup, energyNeededForEqualSupply);
-					continue outerLoop;
-				} else {
-					supply(con, sup, energyRdyToSupply);
-					energyNeededForEqualSupply -= energyRdyToSupply;
-				}
-			}
-			// No more Energy in the network
-			break;
-		}
-		calculateStates();
-	}
-
-	private void calculateStates() {
-		// CalculateStates:
-		supplierList.forEach(sup -> sup.setState(HolonObjectState.PRODUCER));
-		passivNoEnergyList.forEach(sup -> sup.setState(HolonObjectState.NO_ENERGY));
-		for (Consumer con : this.consumerList) {
-			setConsumerState(con);
-		}
-		for (Consumer con : this.consumerSelfSuppliedList) {
-			setConsumerState(con);
-		}
-	}
-
-	private void categorize(MinimumNetwork minimumNetwork, int Iteration) {
-		// Categorize
-		for (HolonObject hObject : minimumNetwork.getHolonObjectList()) {
-			float energyNeeded = hObject.getEnergyNeededFromConsumingElements();
-			float energySelfProducing = hObject.getEnergySelfProducingFromProducingElements();
-			if (energyNeeded < energySelfProducing) {
-				Supplier sup = new Supplier(hObject, energySelfProducing - energyNeeded, energyNeeded);
-				supplierList.add(sup);
-			} else if (energyNeeded > energySelfProducing) {
-				Consumer con = new Consumer(hObject);
-				con.setEnergyNeededFromNetwork(energyNeeded - energySelfProducing);
-				con.setMinimumConsumingElementEnergy(hObject.getMinimumConsumingElementEnergy());
-				con.setEnergyFromConsumingElemnets(hObject.getEnergyNeededFromConsumingElements());
-				con.setEnergySelfSupplied(hObject.getEnergySelfProducingFromProducingElements());
-				consumerList.add(con);
-			} else if (energyNeeded == energySelfProducing) {
-
-				if (energySelfProducing == 0.0f) {
-					Passiv pas = new Passiv(hObject);
-					passivNoEnergyList.add(pas);
-				} else {
-					Consumer con = new Consumer(hObject);
-					con.setEnergyNeededFromNetwork(0.0f);
-					con.setMinimumConsumingElementEnergy(hObject.getMinimumConsumingElementEnergy());
-					con.setEnergyFromConsumingElemnets(hObject.getEnergyNeededFromConsumingElements());
-					con.setEnergySelfSupplied(hObject.getEnergySelfProducingFromProducingElements());
-					consumerSelfSuppliedList.add(con);
-				}
-
-			}
-		}
-	}
-
-	private void setConsumerState(Consumer con) {
-		if (con.getEnergySelfSupplied() + con.getEnergyFromNetwork() > con.getEnergyFromConsumingElemnets()) {
-			con.setState(HolonObjectState.OVER_SUPPLIED);
-		} else if (con.getEnergySelfSupplied() + con.getEnergyFromNetwork() == con.getEnergyFromConsumingElemnets()) {
-			con.setState(HolonObjectState.SUPPLIED);
-		} else if (con.getEnergySelfSupplied() + con.getEnergyFromNetwork() >= con.getMinimumConsumingElementEnergy()) {
-			con.setState(HolonObjectState.PARTIALLY_SUPPLIED);
-		} else {
-			con.setState(HolonObjectState.NOT_SUPPLIED);
-		}
-	}
-
-	/**
-	 * No Checks.
-	 * 
-	 * @param con
-	 * @param sup
-	 * @param energy
-	 */
-	private void supply(Consumer con, Supplier sup, float energy) {
-		sup.getConsumerList().add(sup.new ConsumerListEntry(con, energy));
-		sup.setEnergySupplied(sup.getEnergySupplied() + energy);
-		con.getSupplierList().add(con.new SupplierListEntry(sup, energy));
-		con.setEnergyFromNetwork(con.getEnergyFromNetwork() + energy);
-	}
-
-	public int getAmountOfActiveElements() {
-
-		return supplierList.stream().map(object -> object.getModel().getNumberOfActiveElements()).reduce(0,
-				Integer::sum)
-				+ consumerList.stream().map(object -> object.getModel().getNumberOfActiveElements()).reduce(0,
-						Integer::sum)
-				+ consumerSelfSuppliedList.stream().map(object -> object.getModel().getNumberOfActiveElements())
-						.reduce(0, Integer::sum);
-	}
-
-	public int getAmountOfElements() {
-
-		return supplierList.stream().map(object -> object.getModel().getNumberOfElements()).reduce(0, Integer::sum)
-				+ consumerList.stream().map(object -> object.getModel().getNumberOfElements()).reduce(0, Integer::sum)
-				+ consumerSelfSuppliedList.stream().map(object -> object.getModel().getNumberOfElements()).reduce(0,
-						Integer::sum)
-				+ passivNoEnergyList.stream().map(object -> object.getModel().getNumberOfElements()).reduce(0,
-						Integer::sum);
-	}
-
-	public int getAmountOfConsumer() {
-		return consumerList.size() + this.consumerSelfSuppliedList.size();
-	}
-
-	public int getAmountOfSupplier() {
-		return supplierList.size();
-	}
-
-	public int getAmountOfConsumerWithState(HolonObjectState state) {
-		return (int) (consumerList.stream().filter(con -> con.getState() == state).count()
-				+ consumerSelfSuppliedList.stream().filter(con -> con.getState() == state).count());
-	}
-
-	public int getAmountOfPassiv() {
-		return passivNoEnergyList.size();
-	}
-
-	public int getAmountOfHolonObjects() {
-		return getAmountOfConsumer() + getAmountOfSupplier() + getAmountOfPassiv();
-	}
-
-	public float getTotalConsumption() {
-		float energy = consumerList.stream().map(con -> con.getEnergyFromConsumingElemnets()).reduce(0.f, Float::sum)
-				+ consumerSelfSuppliedList.stream().map(con -> con.getEnergyFromConsumingElemnets()).reduce(0.f,
-						Float::sum);
-		energy += supplierList.stream().map(sup -> sup.getEnergySelfConsuming()).reduce(0.f, Float::sum);
-		return energy;
-	}
-
-	public float getAverageConsumptionInNetworkForHolonObject() {
-		return getTotalConsumption() / (float) getAmountOfHolonObjects();
-	}
-
-	public float getTotalProduction() {
-		float energy = consumerList.stream().map(con -> con.getEnergySelfSupplied()).reduce(0.f, Float::sum)
-				+ consumerSelfSuppliedList.stream().map(con -> con.getEnergySelfSupplied()).reduce(0.f, Float::sum);
-		energy += supplierList.stream().map(sup -> sup.getEnergyProducing()).reduce(0.f, Float::sum);
-		return energy;
-	}
-
-	public float getAverageProductionInNetworkForHolonObject() {
-		return getTotalProduction() / (float) getAmountOfHolonObjects();
-	}
-
-	/**
-	 * returns the Varianz in Poduction
-	 * 
-	 * @return
-	 */
-	public float getVarianzInProductionInNetworkForHolonObjects() {
-		float average = getAverageProductionInNetworkForHolonObject();
-		float sum = consumerList.stream().map(con -> squared(con.getEnergySelfSupplied() - average)).reduce(0.f,
-				Float::sum)
-				+ consumerSelfSuppliedList.stream().map(con -> squared(con.getEnergySelfSupplied() - average))
-						.reduce(0.f, Float::sum)
-				+ supplierList.stream().map(sup -> squared(sup.getEnergyProducing() - average)).reduce(0.f, Float::sum);
-		return sum / (float) getAmountOfHolonObjects();
-	}
-
-	public float getDeviationInProductionInNetworkForHolonObjects() {
-		return (float) Math.sqrt(getVarianzInProductionInNetworkForHolonObjects());
-	}
-
-	public float getVarianzInConsumptionInNetworkForHolonObjects() {
-		float average = getAverageConsumptionInNetworkForHolonObject();
-		float sum = consumerList.stream().map(con -> squared(con.getEnergyFromConsumingElemnets() - average))
-				.reduce(0.f, Float::sum)
-				+ consumerSelfSuppliedList.stream().map(con -> squared(con.getEnergyFromConsumingElemnets() - average))
-						.reduce(0.f, Float::sum)
-				+ supplierList.stream().map(sup -> squared(sup.getEnergySelfConsuming() - average)).reduce(0.f,
-						Float::sum);
-		return sum / (float) getAmountOfHolonObjects();
-	}
-
-	public float getDeviationInConsumptionInNetworkForHolonObjects() {
-		return (float) Math.sqrt(getVarianzInConsumptionInNetworkForHolonObjects());
-	}
-
-	// HelperFunction
-
-	public Stream<HolonElement> getElementStream() {
-		return Stream.concat(consumerList.stream().flatMap(con -> con.getModel().getElements()),
-				Stream.concat(consumerSelfSuppliedList.stream().flatMap(con -> con.getModel().getElements()),
-						Stream.concat(supplierList.stream().flatMap(con -> con.getModel().getElements()),
-								passivNoEnergyList.stream().flatMap(con -> con.getModel().getElements()))));
-	}
-
-	/**
-	 * 
-	 * @return a list of energy
-	 */
-	public Stream<Float> getListOfEnergyThatIsOfferedByFlexibilitiesInThisNetwork() {
-		return getElementStream()
-				.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 getVarianzInFlexibilitieConsumption() {
-		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(getVarianzInFlexibilitieConsumption());
-	}
-
-	public float getDiviationInFlexibilityProduction() {
-		return (float) Math.sqrt(getVarianzInFlexibilitieProduction());
-	}
-
-	// Help Function
-	private float squared(float input) {
-		return input * input;
-	}
-
-}

+ 0 - 111
src/holeg/ui/model/MinimumModel.java

@@ -1,111 +0,0 @@
-package holeg.ui.model;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import holeg.model.AbstractCanvasObject;
-import holeg.model.Edge;
-import holeg.model.GroupNode;
-import holeg.model.HolonObject;
-import holeg.model.HolonSwitch;
-import holeg.model.Node;
-
-/**
- * For DecoratedState And VisualRepresentationalState
- * @author Tom
- *
- */
-public class MinimumModel {
-	
-	
-	
-	
-	private ArrayList<HolonObject> holonObjectList = new ArrayList<>();
-	private ArrayList<Edge> edgeList = new ArrayList<>();
-	private ArrayList<Node> nodeList = new ArrayList<>();
-	private ArrayList<HolonSwitch> switchList = new ArrayList<>();
-	//-->Only for Visual:
-	private ArrayList<GroupNode> groupNodeList = new ArrayList<>();
-	HashMap<Edge, ArrayList<GroupNode>> inGroupEdges = new HashMap<>();
-	//<--
-	
-	
-	
-	
-	
-	public HashMap<Edge, ArrayList<GroupNode>> getInGroupEdges() {
-		return inGroupEdges;
-	}
-
-	public MinimumModel(GroupNode canvas, List<Edge> edgeList, int timestep) {// Constructor because of old Model
-		 canvas.getObjectsInThisLayer().forEach(aCps -> {
-			 if (aCps instanceof HolonObject hObject) {
-				 holonObjectList.add(hObject);
-			 }
-			 else if (aCps instanceof Node node) nodeList.add(node);
-			 else if (aCps instanceof HolonSwitch sw) switchList.add(sw);
-			 else if(aCps instanceof GroupNode groupnode) {
-				 addGroupNodeObjects(groupnode, timestep);
-				 groupNodeList.add(groupnode);
-			 }
-		 });
-		 
-		for (Edge edge : edgeList) {
-			this.edgeList.add(edge);
-			AbstractCanvasObject objectA = edge.getA();
-			AbstractCanvasObject objectB = edge.getB();
-			ArrayList<GroupNode> list = new ArrayList<GroupNode>(); 
-			objectA.getGroupNode().ifPresent(groupNode -> {
-				list.add(groupNode);				
-			});
-			objectB.getGroupNode().ifPresent(groupNode -> {
-				list.add(groupNode);				
-			});
-			inGroupEdges.put(edge, list);
-		}
-		//Calculate Energy of HolonObjects
-		holonObjectList.forEach(obj -> obj.calculateEnergy(timestep));
-	}
-
-
-
-	private void addGroupNodeObjects(GroupNode groupNode, int timestep) {
-		holonObjectList.addAll(groupNode.getAllHolonObjectsRecursive().toList());
-		nodeList.addAll(groupNode.getAllNodeObjectsRecursive().toList());
-		switchList.addAll(groupNode.getAllSwitchObjectsRecursive().toList());
-		groupNodeList.addAll(groupNode.getAllGroupNodeObjectsRecursive().toList());
-	}
-	
-	public ArrayList<HolonObject> getHolonObjectList() {
-		return holonObjectList;
-	}
-	public void setHolonObjectList(ArrayList<HolonObject> holonObjectList) {
-		this.holonObjectList = holonObjectList;
-	}
-	public ArrayList<Edge> getEdgeList() {
-		return edgeList;
-	}
-	public void setEdgeList(ArrayList<Edge> cableList) {
-		this.edgeList = cableList;
-	}
-	public ArrayList<Node> getNodeList() {
-		return nodeList;
-	}
-	public void setNodeList(ArrayList<Node> nodeList) {
-		this.nodeList = nodeList;
-	}
-	public ArrayList<HolonSwitch> getSwitchList() {
-		return switchList;
-	}
-	public void setSwitchList(ArrayList<HolonSwitch> switchList) {
-		this.switchList = switchList;
-	}
-
-	public ArrayList<GroupNode> getUppderNodeList() {
-		return groupNodeList;
-	}
-
-
-	
-}

+ 0 - 41
src/holeg/ui/model/MinimumNetwork.java

@@ -1,41 +0,0 @@
-package holeg.ui.model;
-
-import java.util.ArrayList;
-
-import holeg.model.AbstractCanvasObject;
-import holeg.model.Edge;
-import holeg.model.HolonObject;
-
-public class MinimumNetwork {
-	private ArrayList<HolonObject> holonObjectList = new ArrayList<HolonObject>();
-	private ArrayList<Edge> edgeList = new ArrayList<Edge>();
-	//ToCalculate average path
-	private ArrayList<AbstractCanvasObject> nodeAndSwitches = new ArrayList<AbstractCanvasObject>();
-	public MinimumNetwork(ArrayList<HolonObject> holonObjectList, ArrayList<Edge> edgeList){
-		this.holonObjectList = holonObjectList;
-		this.edgeList = edgeList;
-	}
-	public ArrayList<HolonObject> getHolonObjectList() {
-		return holonObjectList;
-	}
-	public ArrayList<Edge> getEdgeList() {
-		return edgeList;
-	}
-	public String toString()
-	{
-		String objecte = "[";
-		for(HolonObject object :holonObjectList) {
-			objecte += " " + object.getName();
-		}
-		objecte += "]";
-		String edges = "[";
-		for(Edge edge :edgeList) {
-			edges += " " + edge;
-		}
-		edges += "]";
-		return objecte + edges;
-	}
-	public ArrayList<AbstractCanvasObject> getNodeAndSwitches() {
-		return nodeAndSwitches;
-	}
-}

+ 19 - 10
src/holeg/ui/model/Model.java

@@ -1,14 +1,13 @@
 package holeg.ui.model;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
-import holeg.model.Edge;
-import holeg.model.Flexibility;
-import holeg.model.GroupNode;
-import holeg.model.HolonElement;
 
+import holeg.model.*;
 
 
 /**
@@ -45,7 +44,7 @@ public class Model {
     /** the Fairness model in use */
     private FairnessModel fairnessModel = FairnessModel.MininumDemandFirst;
    
-    private GroupNode canvas = new GroupNode("Canvas");
+    private final GroupNode canvas = new GroupNode("Canvas");
     /*
      * Array of all CpsObjects in our canvas. It is set by default as an empty
      * list.
@@ -59,7 +58,12 @@ public class Model {
     public GroupNode getCanvas() {
     	return canvas;
     }
-    
+
+    public Set<Holon> holons = new HashSet<>();
+
+
+
+
 
     /**
      * Get all Edges on the Canvas.
@@ -119,7 +123,7 @@ public class Model {
     /**
      * sets the current Iteration.
      *
-     * @param curIT the current Iteration
+     * @param value the current Iteration
      */
     public void setCurrentIteration(int value) {
         this.currentIteration = value;
@@ -128,7 +132,7 @@ public class Model {
 
 
     public List<HolonElement> getAllHolonElements() {
-    	return canvas.getAllHolonObjectsRecursive().flatMap(hO -> hO.getElements()).collect(Collectors.toList());
+    	return canvas.getAllHolonObjectsRecursive().flatMap(HolonObject::getElements).collect(Collectors.toList());
     }
     
     public List<Flexibility> getAllFlexibilities() {
@@ -141,10 +145,10 @@ public class Model {
     }
     
     private void resetFlexibilities() {
-    	getAllFlexibilities().forEach(flex -> flex.reset());
+    	getAllFlexibilities().forEach(Flexibility::reset);
     }
     private void resetEdges() {
-    	this.getEdgesOnCanvas().forEach(edge -> edge.reset());
+    	this.getEdgesOnCanvas().forEach(Edge::reset);
     }
    
 	
@@ -173,4 +177,9 @@ public class Model {
 		this.edgesOnCanvas.clear();
 		canvas.clear();
 	}
+
+
+
+
+
 }

+ 30 - 32
src/holeg/ui/view/canvas/Rendering.java

@@ -15,11 +15,13 @@ class Rendering {
             RenderingHints.VALUE_ANTIALIAS_ON);
     private static final Font CanvasFont = new Font("TimesNewRoman", Font.PLAIN,
             Math.max((int) (GuiSettings.getPictureScale() / 3.5f), 10));
-    private static Color[] colors = {ColorPreference.HolonObject.Producer, ColorPreference.HolonObject.NotSupplied,
+    private static final Color[] colors = {ColorPreference.HolonObject.Producer, ColorPreference.HolonObject.NotSupplied,
             ColorPreference.HolonObject.PartiallySupplied, ColorPreference.HolonObject.Supplied,
             ColorPreference.HolonObject.OverSupplied, ColorPreference.HolonObject.NoEnergy};
     private static final BasicStroke OnePixelStroke = new BasicStroke(1);
     private static final BasicStroke TwoPixelStroke = new BasicStroke(2);
+    private static final Dimension SupplyBarDimensions = new Dimension(GuiSettings.getPictureScale(), GuiSettings.getPictureScale() / 5);
+    private static final Font SupplyBarFont = new Font("TimesNewRoman", Font.PLAIN, (int) (GuiSettings.getPictureScale() * 0.3) - 2);
 
 
 
@@ -33,15 +35,16 @@ class Rendering {
     static void drawSwitchObject(Graphics2D g, HolonSwitch hS) {
         drawCanvasObject(g, hS);
     }
-
     static void drawHolonObject(Graphics2D g, HolonObject hO) {
         Vec2i pos = hO.getPosition();
-//		Color statecolor = ColorPreference.HolonObject.getStateColor(hO.getState());
-//		g.setColor(statecolor);
-        g.setColor(Color.cyan);
+		Color stateColor = ColorPreference.HolonObject.getStateColor(hO.getState());
+		g.setColor(stateColor);
         g.fillRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() - GuiSettings.getPictureScaleDiv2(),
                 GuiSettings.getPictureScale(), GuiSettings.getPictureScale());
         drawCanvasObject(g, hO.getImage(), pos);
+        if(GuiSettings.showSupplyBars && hO.getActualEnergy() <= 0){
+            drawSupplyBar(g, hO.getSupplyBarPercentage(), stateColor, pos);
+        }
     }
 
     static void drawCanvasObject(Graphics2D g, AbstractCanvasObject obj) {
@@ -71,7 +74,7 @@ class Rendering {
         Vec2i end = edge.getB().getPosition();
         float currentEnergy = edge.getActualFlow();
         float capacity = edge.maxCapacity;
-        boolean unlimited = edge.isUnlimitedCapacity();
+        boolean unlimited = edge.mode == Edge.EdgeMode.Unlimited;
         switch (edge.getState()) {
             case Burned -> {
                 g.setColor(ColorPreference.Edge.Burned);
@@ -82,9 +85,6 @@ class Rendering {
                 g.setStroke(new BasicStroke(unlimited ? 2f : (currentEnergy / capacity * 2f) + 1));
             }
         }
-//		if (isSelected) {
-//			g.setColor(Color.lightGray);
-//		}
         g.drawLine(start.getX(), start.getY(), end.getX(), end.getY());
         Vec2i middle = new Vec2i((start.getX() + end.getX()) / 2, (start.getY() + end.getY()) / 2);
         g.drawString(currentEnergy + "/" + (unlimited ? "\u221E" : capacity), middle.getX(), middle.getY());
@@ -271,27 +271,25 @@ class Rendering {
 //	return percentages;
 //}
 
-//private void paintSupplyBar(Graphics2D g, float percentage, Color color, Vec2i pos) {
-//	// +1, -2, -1 little Adjustment for pixel perfect alignment
-//	int barWidth = (int) (GuiSettings.getPictureScale());
-//	int barHeight = (int) (GuiSettings.getPictureScale() / 5);
-//	g.setColor(Color.WHITE);
-//	g.fillRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() + GuiSettings.getPictureScaleDiv2() - 1, (int) barWidth,
-//			barHeight);
-//	g.setColor(color);
-//	g.fillRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() + GuiSettings.getPictureScaleDiv2() - 1,
-//			(int) (barWidth * (percentage < 1 ? percentage : 1.0f) - 1), barHeight);
-//	g.setColor(Color.BLACK);
-//	g.setStroke(new BasicStroke(1));
-//	g.drawRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() + GuiSettings.getPictureScaleDiv2() - 1, barWidth - 1,
-//			barHeight);
-//	g.setFont(new Font("TimesNewRoman", Font.PLAIN, (int) (barHeight * 1.5) - 2));
-//	String percentageString = (Math.round((percentage * 100))) + "%";
-//	int stringWidth = (int) g.getFontMetrics().getStringBounds(percentageString, g).getWidth();
-//	if (percentage > 1.0f)
-//		g.setColor(Color.WHITE); // Just to see better on purple
-//	g.drawString(percentageString, pos.getX() + 1 - stringWidth / 2,
-//			pos.getY() + GuiSettings.getPictureScaleDiv2() - 1 + barHeight);
-//
-//}
+private static void drawSupplyBar(Graphics2D g, float percentage, Color color, Vec2i pos) {
+	// +1, -2, -1 little Adjustment for pixel perfect alignment
+	g.setColor(Color.WHITE);
+	g.fillRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() + GuiSettings.getPictureScaleDiv2() - 1, SupplyBarDimensions.width,
+            SupplyBarDimensions.height);
+	g.setColor(color);
+	g.fillRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() + GuiSettings.getPictureScaleDiv2() - 1,
+			(int) (SupplyBarDimensions.width * (percentage < 1 ? percentage : 1.0f) - 1), SupplyBarDimensions.height);
+	g.setColor(Color.BLACK);
+	g.setStroke(new BasicStroke(1));
+	g.drawRect(pos.getX() - GuiSettings.getPictureScaleDiv2(), pos.getY() + GuiSettings.getPictureScaleDiv2() - 1, SupplyBarDimensions.width - 1,
+            SupplyBarDimensions.height);
+	g.setFont(SupplyBarFont);
+	String percentageString = (Math.round((percentage * 100))) + "%";
+	int stringWidth = (int) g.getFontMetrics().getStringBounds(percentageString, g).getWidth();
+	if (percentage > 1.0f){
+        g.setColor(Color.WHITE); // Just to see better on purple
+    }
+	g.drawString(percentageString, pos.getX() + 1 - stringWidth / 2,
+			pos.getY() + GuiSettings.getPictureScaleDiv2() - 1 + SupplyBarDimensions.height);
+}
 }

+ 0 - 1
src/holeg/ui/view/dialog/CanvasResizePopUp.java

@@ -77,7 +77,6 @@ public class CanvasResizePopUp extends JDialog {
 					position.clampX(0, actualCanvasSize.getX());
 					position.clampY(0, actualCanvasSize.getY());
 				});
-				controller.updateCanvas();
 				dispose();
 			}
 		});

+ 2 - 3
src/holeg/ui/view/window/FlexWindow.java

@@ -229,7 +229,6 @@ public class FlexWindow extends JFrame {
 			labelButton.addActionListener(clicked ->{
 				flex.order();
 				control.calculateStateAndVisualForCurrentTimeStep();
-				control.updateCanvas();
 			});
 			labelButton.setToolTipText(createToolTipp(flex));
 			i++;
@@ -449,7 +448,7 @@ public class FlexWindow extends JFrame {
 		Flexibility toDeleteFlex =(Flexibility) JOptionPane.showInputDialog(this, "Select to Delete Flexibility:", "Flexibility?",  JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , allFlexes, "");
 		if(toDeleteFlex != null) {
 			toDeleteFlex.getElement().flexList.remove(toDeleteFlex);
-			control.getSimManager().calculateStateForTimeStep(model.getCurrentIteration(), true);
+			control.getSimManager().calculateStateForTimeStep(model.getCurrentIteration());
 			updateSelectedPanel();
 		}
 	}
@@ -664,7 +663,7 @@ public class FlexWindow extends JFrame {
 			
 			
 			//if(!model.getSelectedCpsObjects().contains(holonObjectSelector.getSelectedItem()))model.getSelectedCpsObjects().add((AbstractCpsObject)holonObjectSelector.getSelectedItem());
-			control.getSimManager().calculateStateForTimeStep(model.getCurrentIteration(), true);
+			control.getSimManager().calculateStateForTimeStep(model.getCurrentIteration());
 			
 			update();
 			addDialog.dispose();

+ 3 - 3
src/holeg/ui/view/window/Outliner.java

@@ -2,7 +2,7 @@ package holeg.ui.view.window;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
-import java.util.ArrayList;
+import java.util.Set;
 import java.util.logging.Logger;
 
 import javax.swing.ImageIcon;
@@ -19,7 +19,7 @@ import javax.swing.tree.DefaultTreeCellRenderer;
 import holeg.model.AbstractCanvasObject;
 import holeg.preferences.ImagePreference;
 import holeg.ui.controller.Control;
-import holeg.ui.model.MinimumNetwork;
+import holeg.model.Holon;
 import holeg.ui.model.Model;
 import holeg.ui.view.image.Import;
 import holeg.utility.listener.WindowClosingListener;
@@ -30,7 +30,7 @@ public class Outliner extends JFrame {
 	JTabbedPane tabbedPane = new JTabbedPane();
 	JPanel listPanel = new JPanel(new BorderLayout());
 	JPanel statePanel = new JPanel(new BorderLayout());
-	ArrayList<MinimumNetwork> list;
+	Set<Holon> list;
 	Runnable update = this::update;
 
 	public Outliner(JFrame parentFrame, Model model, Control control) {