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.Edge.EdgeState; import holeg.model.HolonSwitch.SwitchState; import holeg.ui.model.MinimumModel; import holeg.ui.model.MinimumNetwork; 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 list = new ArrayList(); MinimumModel minimumModel = new MinimumModel(model.getCanvas(), model.getEdgesOnCanvas(), model.getCurrentIteration()); ArrayList leftOver = new ArrayList(); 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 decorNetworks = new ArrayList(); // FairnessModel actualFairnessModel = model.getFairnessModel(); // for (MinimumNetwork net : list) { // decorNetworks.add(new DecoratedNetwork(net, timestep, actualFairnessModel)); // } 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"); } /** * SubFunction to calculate the Networks from the model. * * @param minModel * @param Iteration * @param leftOver * @return */ ArrayList calculateNetworks(MinimumModel minModel, int Iteration, ArrayList leftOver) { // Copy minModel ObjectList ArrayList holonObjectList = new ArrayList(); for (HolonObject holonObject : minModel.getHolonObjectList()) { holonObjectList.add(holonObject); } // Copy minModelEdgeList ArrayList edgeList = new ArrayList(); for (Edge cable : minModel.getEdgeList()) { edgeList.add(cable); } ArrayList listOfNetworks = new ArrayList(); 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(), new ArrayList()); actualNetwork.getHolonObjectList().add(lookAtObject); // create List of neighbors LinkedList neighbors = new LinkedList(); 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; } /** * Adds the neighbors. * * @param edgeList * @param lookAtObject * @param actualNetwork * @param neighbors */ void populateListOfNeighbors(ArrayList edgeList, AbstractCanvasObject lookAtObject, MinimumNetwork actualNetwork, LinkedList neighbors) { ListIterator iter = edgeList.listIterator(); while (iter.hasNext()) { Edge lookAtEdge = iter.next(); if (lookAtEdge.getState() == EdgeState.Working && lookAtEdge.isConnectedTo(lookAtObject)) { iter.remove(); actualNetwork.getEdgeList().add(lookAtEdge); // Add neighbar AbstractCanvasObject edgeNeighbor; if (lookAtEdge.getA().equals(lookAtObject)) { edgeNeighbor = lookAtEdge.getB(); } else { edgeNeighbor = lookAtEdge.getA(); } if (!neighbors.contains(edgeNeighbor)) { neighbors.add(edgeNeighbor); } } } } }