package api; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.math.RoundingMode; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collections; import java.util.DoubleSummaryStatistics; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JSplitPane; import javax.swing.text.NumberFormatter; import algorithm.objectiveFunction.TopologieObjectiveFunction; import classes.AbstractCanvasObject; import classes.Category; import classes.Edge; import classes.GroupNode; import classes.HolonObject; import classes.HolonSwitch; import classes.IdCounterElem; import classes.Node; import ui.controller.Control; import ui.model.DecoratedGroupNode; import ui.model.DecoratedState; import ui.model.Model; import ui.model.DecoratedHolonObject.HolonObjectState; import ui.model.DecoratedSwitch.SwitchState; import ui.model.DecoratedNetwork; import ui.view.Console; public abstract class TopologieAlgorithmFramework implements AddOn{ //Algo protected int rounds = 1; protected int amountOfNewCables = 20; //Panel private JPanel content = new JPanel(); protected Console console = new Console(); private JPanel borderPanel = new JPanel(); private HashMap panelMap = new HashMap(); //Settings groupNode private DecoratedGroupNode dGroupNode = null; //access private ArrayList accessWildcards = new ArrayList(); LinkedList> resetChain = new LinkedList>(); private HashMap accessIntToObject = new HashMap(); private HashMap accessObjectToInt = new HashMap(); private HashMap accessIntegerToWildcard = new HashMap(); private HashMap accessGroupNode = new HashMap(); private HashSet cableSet = new HashSet(); private ArrayList cableList = new ArrayList(); private HashMap addedIndexCable = new HashMap(); private int countForAccessMap = 0; private int amountOfExistingCables = 0; private ArrayList switchList = new ArrayList(); private HashMap accessSwitchGroupNode = new HashMap(); private ArrayList edgeList = new ArrayList(); boolean algoUseElements = false, algoUseSwitches = true, algoUseFlexes = true; //time private long startTime; private RunProgressBar runProgressbar = new RunProgressBar(); //concurrency private Thread runThread = new Thread(); protected boolean cancel = false; //holeg interaction protected Control control; //printing private Printer runPrinter = new Printer(plottFileName()); protected List runList = new LinkedList(); //Parameter @SuppressWarnings("rawtypes") LinkedList parameterSteppingList= new LinkedList(); protected boolean useStepping = false; //SwitchButton public TopologieAlgorithmFramework(){ content.setLayout(new BorderLayout()); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createOptionPanel() , console); splitPane.setResizeWeight(0.0); content.add(splitPane, BorderLayout.CENTER); content.setPreferredSize(new Dimension(1200,800)); } private JPanel createOptionPanel() { JPanel optionPanel = new JPanel(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(createParameterPanel()); scrollPane.setBorder(BorderFactory.createTitledBorder("Parameters")); optionPanel.add(scrollPane, BorderLayout.CENTER); optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END); return optionPanel; } private JPanel createParameterPanel() { JPanel parameterPanel = new JPanel(null); parameterPanel.setPreferredSize(new Dimension(510,300)); borderPanel.setLayout(new BoxLayout(borderPanel, BoxLayout.PAGE_AXIS)); addIntParameter("Number of New Cables", amountOfNewCables, intInput -> amountOfNewCables = intInput, () -> amountOfNewCables, 0); addSeperator(); addIntParameter("Repetitions", rounds, intInput -> rounds = intInput, () -> rounds, 1); JScrollPane scrollPane = new JScrollPane(borderPanel); scrollPane.setBounds(10, 0, 850, 292); scrollPane.setBorder(BorderFactory.createEmptyBorder()); parameterPanel.add(scrollPane); JProgressBar progressBar = runProgressbar.getJProgressBar(); progressBar.setBounds(900, 35, 185, 20); progressBar.setStringPainted(true); parameterPanel.add(progressBar); JButton addCategoryButton = new JButton("Add Category"); addCategoryButton.setBounds(900, 65, 185, 30); addCategoryButton.addActionListener(clicked -> createWildcardsCategory()); parameterPanel.add(addCategoryButton); return parameterPanel; } private JPanel createButtonPanel() { JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); JButton toggleSwitchesButton = new JButton("Toggle Switches"); toggleSwitchesButton.setToolTipText("Set all switches active or inactive."); toggleSwitchesButton.addActionListener(actionEvent -> toggleSwitches()); buttonPanel.add(toggleSwitchesButton); JButton resetButton = new JButton("Reset"); resetButton.setToolTipText("Resets the State to before the Algorithm has runed."); resetButton.addActionListener(actionEvent -> reset()); buttonPanel.add(resetButton); JButton cancelButton = new JButton("Cancel Run"); cancelButton.addActionListener(actionEvent -> cancel()); buttonPanel.add(cancelButton); JButton fitnessButton = new JButton("Fitness"); fitnessButton.setToolTipText("Fitness for the current state."); fitnessButton.addActionListener(actionEvent -> fitness()); buttonPanel.add(fitnessButton); JButton runButton = new JButton("Run"); runButton.addActionListener(actionEvent -> { if(runThread.isAlive()) { return; } reset(); this.resetAllList(); resetChain.clear(); Runnable task = () -> run(); runThread = new Thread(task); runThread.start(); }); buttonPanel.add(runButton); return buttonPanel; } //ParameterImports private void toggleSwitches() { List allSwitchList = control.getModel().getAllSwitches(); if(allSwitchList.isEmpty()) return; boolean set = allSwitchList.get(0).getState(control.getModel().getCurIteration()); allSwitchList.forEach(hSwitch -> { hSwitch.setManualMode(true); hSwitch.setManualState(!set); }); updateVisual(); } //addSeperator protected void addSeperator() { borderPanel.add(Box.createRigidArea(new Dimension(5, 5))); borderPanel.add(new JSeparator()); borderPanel.add(Box.createRigidArea(new Dimension(5, 5))); } //int protected void addIntParameter(String parameterName, int parameterValue, Consumer setter, Supplier getter) { this.addIntParameter(parameterName, parameterValue, setter, getter, true, Integer.MIN_VALUE, Integer.MAX_VALUE); } protected void addIntParameter(String parameterName, int parameterValue, Consumer setter, Supplier getter, int parameterMinValue) { this.addIntParameter(parameterName, parameterValue, setter, getter, true, parameterMinValue, Integer.MAX_VALUE); } protected void addIntParameter(String parameterName, int parameterValue, Consumer setter, Supplier getter, boolean visible, int parameterMinValue, int parameterMaxValue) { JPanel singleParameterPanel = new JPanel(); singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS)); singleParameterPanel.setAlignmentX(0.0f); singleParameterPanel.add(new JLabel(parameterName + ": ")); singleParameterPanel.add(Box.createHorizontalGlue()); NumberFormat format = NumberFormat.getIntegerInstance(); format.setGroupingUsed(false); format.setParseIntegerOnly(true); NumberFormatter integerFormatter = new NumberFormatter(format); integerFormatter.setMinimum(parameterMinValue); integerFormatter.setMaximum(parameterMaxValue); integerFormatter.setCommitsOnValidEdit(true); JFormattedTextField singleParameterTextField = new JFormattedTextField(integerFormatter); singleParameterTextField.setValue(parameterValue); String minValue = (parameterMinValue == Integer.MIN_VALUE)?"Integer.MIN_VALUE":String.valueOf(parameterMinValue); String maxValue = (parameterMaxValue == Integer.MAX_VALUE)?"Integer.MAX_VALUE":String.valueOf(parameterMaxValue); singleParameterTextField.setToolTipText("Only integer \u2208 [" + minValue + "," + maxValue + "]"); singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(Integer.parseInt(singleParameterTextField.getValue().toString()))); singleParameterTextField.setMaximumSize(new Dimension(200, 30)); singleParameterTextField.setPreferredSize(new Dimension(200, 30)); singleParameterPanel.add(singleParameterTextField); ParameterStepping intParameterStepping = new ParameterStepping(setter, getter, Integer::sum , (a,b) -> a * b, 1, 1); intParameterStepping.useThisParameter = false; parameterSteppingList.add(intParameterStepping); JCheckBox useSteppingCheckBox = new JCheckBox(); useSteppingCheckBox.setSelected(false); singleParameterPanel.add(useSteppingCheckBox); JLabel stepsLabel = new JLabel("Steps: "); stepsLabel.setEnabled(false); singleParameterPanel.add(stepsLabel); NumberFormatter stepFormatter = new NumberFormatter(format); stepFormatter.setMinimum(1); stepFormatter.setMaximum(Integer.MAX_VALUE); stepFormatter.setCommitsOnValidEdit(true); JFormattedTextField stepsTextField = new JFormattedTextField(stepFormatter); stepsTextField.setEnabled(false); stepsTextField.setValue(1); stepsTextField.setToolTipText("Only integer \u2208 [" + 1 + "," + Integer.MAX_VALUE + "]"); stepsTextField.addPropertyChangeListener(actionEvent -> intParameterStepping.stepps = Integer.parseInt(stepsTextField.getValue().toString())); stepsTextField.setMaximumSize(new Dimension(40, 30)); stepsTextField.setPreferredSize(new Dimension(40, 30)); singleParameterPanel.add(stepsTextField); JLabel stepsSizeLabel = new JLabel("StepsSize: "); stepsSizeLabel.setEnabled(false); singleParameterPanel.add(stepsSizeLabel); JFormattedTextField stepsSizeTextField = new JFormattedTextField(stepFormatter); stepsSizeTextField.setEnabled(false); stepsSizeTextField.setValue(1); stepsSizeTextField.setToolTipText("Only integer \u2208 [" + 1 + "," + Integer.MAX_VALUE + "]"); stepsSizeTextField.addPropertyChangeListener(actionEvent -> intParameterStepping.stepSize = Integer.parseInt(stepsSizeTextField.getValue().toString())); stepsSizeTextField.setMaximumSize(new Dimension(40, 30)); stepsSizeTextField.setPreferredSize(new Dimension(40, 30)); singleParameterPanel.add(stepsSizeTextField); useSteppingCheckBox.addActionListener(actionEvent -> { boolean enabled = useSteppingCheckBox.isSelected(); intParameterStepping.useThisParameter = enabled; this.useStepping = this.parameterSteppingList.stream().anyMatch(parameter -> parameter.useThisParameter); stepsLabel.setEnabled(enabled); stepsTextField.setEnabled(enabled); stepsSizeLabel.setEnabled(enabled); stepsSizeTextField.setEnabled(enabled); }); panelMap.put(parameterName, singleParameterPanel); singleParameterPanel.setVisible(visible); borderPanel.add(singleParameterPanel); } //double protected void addDoubleParameter(String parameterName, double parameterValue, Consumer setter, Supplier getter) { this.addDoubleParameter(parameterName, parameterValue, setter, getter, true, Double.MIN_VALUE, Double.MAX_VALUE); } protected void addDoubleParameter(String parameterName, double parameterValue, Consumer setter, Supplier getter, double parameterMinValue) { this.addDoubleParameter(parameterName, parameterValue, setter, getter, true, parameterMinValue, Double.MAX_VALUE); } protected void addDoubleParameter(String parameterName, double parameterValue, Consumer setter, Supplier getter, boolean visible, double parameterMinValue, double parameterMaxValue) { JPanel singleParameterPanel = new JPanel(); singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS)); singleParameterPanel.setAlignmentX(0.0f); singleParameterPanel.add(new JLabel(parameterName + ": ")); singleParameterPanel.add(Box.createHorizontalGlue()); NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US); doubleFormat.setMinimumFractionDigits(1); doubleFormat.setMaximumFractionDigits(10); doubleFormat.setRoundingMode(RoundingMode.HALF_UP); NumberFormatter doubleFormatter = new NumberFormatter(doubleFormat); doubleFormatter.setMinimum(parameterMinValue); doubleFormatter.setMaximum(parameterMaxValue); doubleFormatter.setCommitsOnValidEdit(true); JFormattedTextField singleParameterTextField = new JFormattedTextField(doubleFormatter); singleParameterTextField.setValue(parameterValue); String minValue = (parameterMinValue == Double.MIN_VALUE)?"Double.MIN_VALUE":String.valueOf(parameterMinValue); String maxValue = (parameterMaxValue == Double.MAX_VALUE)?"Double.MAX_VALUE":String.valueOf(parameterMaxValue); singleParameterTextField.setToolTipText("Only double \u2208 [" + minValue + "," + maxValue + "]"); singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(Double.parseDouble(singleParameterTextField.getValue().toString()))); singleParameterTextField.setMaximumSize(new Dimension(200, 30)); singleParameterTextField.setPreferredSize(new Dimension(200, 30)); singleParameterPanel.add(singleParameterTextField); ParameterStepping doubleParameterStepping = new ParameterStepping(setter, getter, (a,b) -> a+b , (a,b) -> a * b, 1.0, 1); doubleParameterStepping.useThisParameter = false; parameterSteppingList.add(doubleParameterStepping); JCheckBox useSteppingCheckBox = new JCheckBox(); useSteppingCheckBox.setSelected(false); singleParameterPanel.add(useSteppingCheckBox); JLabel stepsLabel = new JLabel("Steps: "); stepsLabel.setEnabled(false); singleParameterPanel.add(stepsLabel); NumberFormat format = NumberFormat.getIntegerInstance(); format.setGroupingUsed(false); format.setParseIntegerOnly(true); NumberFormatter integerFormatter = new NumberFormatter(format); integerFormatter.setMinimum(1); integerFormatter.setMaximum(Integer.MAX_VALUE); integerFormatter.setCommitsOnValidEdit(true); JFormattedTextField stepsTextField = new JFormattedTextField(integerFormatter); stepsTextField.setEnabled(false); stepsTextField.setValue(1); stepsTextField.setToolTipText("Only integer \u2208 [" + 1 + "," + Integer.MAX_VALUE + "]"); stepsTextField.addPropertyChangeListener(actionEvent -> doubleParameterStepping.stepps = Integer.parseInt(stepsTextField.getValue().toString())); stepsTextField.setMaximumSize(new Dimension(40, 30)); stepsTextField.setPreferredSize(new Dimension(40, 30)); singleParameterPanel.add(stepsTextField); JLabel stepsSizeLabel = new JLabel("StepsSize: "); stepsSizeLabel.setEnabled(false); singleParameterPanel.add(stepsSizeLabel); NumberFormatter doubleFormatterForStepping = new NumberFormatter(doubleFormat); doubleFormatterForStepping.setCommitsOnValidEdit(true); JFormattedTextField stepsSizeTextField = new JFormattedTextField(doubleFormatterForStepping); stepsSizeTextField.setEnabled(false); stepsSizeTextField.setValue(1.0); stepsSizeTextField.setToolTipText("Only double"); stepsSizeTextField.addPropertyChangeListener(actionEvent -> doubleParameterStepping.stepSize = Double.parseDouble(stepsSizeTextField.getValue().toString())); stepsSizeTextField.setMaximumSize(new Dimension(40, 30)); stepsSizeTextField.setPreferredSize(new Dimension(40, 30)); singleParameterPanel.add(stepsSizeTextField); useSteppingCheckBox.addActionListener(actionEvent -> { boolean enabled = useSteppingCheckBox.isSelected(); doubleParameterStepping.useThisParameter = enabled; this.useStepping = this.parameterSteppingList.stream().anyMatch(parameter -> parameter.useThisParameter); stepsLabel.setEnabled(enabled); stepsTextField.setEnabled(enabled); stepsSizeLabel.setEnabled(enabled); stepsSizeTextField.setEnabled(enabled); }); panelMap.put(parameterName, singleParameterPanel); singleParameterPanel.setVisible(visible); borderPanel.add(singleParameterPanel); } //boolean protected void addBooleanParameter(String parameterName, boolean parameterValue, Consumer setter, List showParameterNames, List hideParameterNames){ JPanel singleParameterPanel = new JPanel(); panelMap.put(parameterName, singleParameterPanel); singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS)); singleParameterPanel.setAlignmentX(0.0f); singleParameterPanel.add(new JLabel(parameterName + ": ")); singleParameterPanel.add(Box.createHorizontalGlue()); JCheckBox useGroupNodeCheckBox = new JCheckBox(); useGroupNodeCheckBox.addActionListener(actionEvent -> { setter.accept(useGroupNodeCheckBox.isSelected()); showParameterNames.forEach(string -> panelMap.get(string).setVisible(useGroupNodeCheckBox.isSelected())); hideParameterNames.forEach(string -> panelMap.get(string).setVisible(!useGroupNodeCheckBox.isSelected())); }); useGroupNodeCheckBox.setSelected(parameterValue); singleParameterPanel.add(useGroupNodeCheckBox); borderPanel.add(singleParameterPanel); } private void startTimer(){ startTime = System.currentTimeMillis(); } private long printElapsedTime(){ long elapsedMilliSeconds = System.currentTimeMillis() - startTime; console.println("Execution Time of Algo in Milliseconds:" + elapsedMilliSeconds); return elapsedMilliSeconds; } private void cancel() { if(runThread.isAlive()) { console.println("Cancel run."); cancel = true; runProgressbar.cancel(); } else { console.println("Nothing to cancel."); } } private void createWildcardsCategory() { Category category = control.searchCategory("Wildcards"); if(category == null) { try { control.addCategory("Wildcards"); } catch (IOException e) { console.println("IO Exception - Creating WIldcards Category failed."); System.out.println("IO Exception - Creating WIldcards Category failed."); e.printStackTrace(); } } } private void fitness() { if(runThread.isAlive()) { console.println("Run have to be cancelled First."); return; } // reset(); // this.extractPositionAndAccess(); double currentFitness = evaluateNetworkAndPrint(); console.println("Actual Fitnessvalue: " + currentFitness); } protected double evaluatePosition(List positionToEvaluate) { setState(positionToEvaluate); // execution time critical return evaluateNetwork(); } private double evaluateNetwork() { runProgressbar.step(); DecoratedState actualstate = control.getSimManager().getActualDecorState(); return evaluateState(actualstate, calculateAmountOfAddedSwitches(), addedCableMeter(), false); } private double evaluateNetworkAndPrint() { runProgressbar.step(); for(HolonSwitch hSwitch: switchList) { hSwitch.setManualMode(true); hSwitch.setManualState(false); } control.calculateStateOnlyForCurrentTimeStep(); DecoratedState actualstate = control.getSimManager().getActualDecorState(); return evaluateState(actualstate, calculateAmountOfAddedSwitches(), addedCableMeter(), true); } private double addedCableMeter() { return addedIndexCable.values().stream().reduce(0.0, Double::sum); } private int calculateAmountOfAddedSwitches() { return (int)this.switchList.stream().filter(sw -> sw.getName().contains("AddedSwitch")).count(); } protected abstract double evaluateState(DecoratedState actualstate, int amountOfAddedSwitch, double addedCableMeter, boolean moreInfromation); private void run() { cancel = false; control.guiDisable(true); runPrinter.openStream(); runPrinter.println(""); runPrinter.println("Start:" + stringStatFromActualState()); runPrinter.closeStream(); if(this.useStepping) { initParameterStepping(); do { executeAlgoWithParameter(); if(cancel) break; resetState(); }while(updateOneParameter()); resetParameterStepping(); }else { executeAlgoWithParameter(); } TopologieObjectiveFunction.log.clear(); updateVisual(); runProgressbar.finishedCancel(); control.guiDisable(false); } @SuppressWarnings("rawtypes") private void initParameterStepping() { for(ParameterStepping param :this.parameterSteppingList) { param.init(); } } @SuppressWarnings("rawtypes") private void resetParameterStepping() { for(ParameterStepping param :this.parameterSteppingList) { param.reset(); } } @SuppressWarnings("rawtypes") private boolean updateOneParameter() { List parameterInUseList = this.parameterSteppingList.stream().filter(param -> param.useThisParameter).collect(Collectors.toList()); Collections.reverse(parameterInUseList); int lastParameter = parameterInUseList.size() - 1 ; int actualParameter = 0; for(ParameterStepping param : parameterInUseList) { if(param.canUpdate()) { param.update(); return true; }else { if(actualParameter == lastParameter) break; param.reset(); } actualParameter++; } //No Param can be updated return false; } private void executeAlgoWithParameter(){ double startFitness = evaluatePosition(extractPositionAndAccess()); resetChain.removeLast(); runPrinter.openStream(); runPrinter.println(""); runPrinter.println(algoInformationToPrint()); runPrinter.closeStream(); console.println(algoInformationToPrint()); runProgressbar.start(); Individual runBest = new Individual(); runBest.fitness = Double.MAX_VALUE; for(int r = 0; r < rounds; r++) { resetState(); startTimer(); Individual roundBest = executeAlgo(); if(cancel)return; long executionTime = printElapsedTime(); setState(roundBest.position); runPrinter.openStream(); runPrinter.println(runList.stream().map(Object::toString).collect(Collectors.joining(", "))); runPrinter.println(stringStatFromActualState()); runPrinter.println("Result: " + roundBest.fitness + " ExecutionTime:" + executionTime); runPrinter.closeStream(); if(roundBest.fitness < runBest.fitness) runBest = roundBest; } control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration()); setState(runBest.position); for(HolonSwitch hSwitch: switchList) { hSwitch.setManualMode(true); hSwitch.setManualState(false); } updateVisual(); evaluateNetworkAndPrint(); console.println("Start: " + startFitness); console.println("AlgoResult: " + runBest.fitness); } protected abstract Individual executeAlgo(); private void reset() { if(runThread.isAlive()) { console.println("Run have to be cancelled First."); return; } if(!resetChain.isEmpty()) { console.println("Resetting.."); setState(resetChain.getFirst()); resetChain.clear(); control.resetSimulation(); control.setCurIteration(0); updateVisual(); }else { console.println("No run inistialized."); } } /** * To let the User See the current state without touching the Canvas. */ private void updateVisual() { control.calculateStateAndVisualForCurrentTimeStep(); } /** * Sets the Model back to its original State before the LAST run. */ private void resetState() { if(!resetChain.isEmpty()) { setState(resetChain.removeLast()); } resetAllList(); } /** * Sets the State out of the given position for calculation or to show the user. * @param position */ private void setState(List position) { this.removeAllAddedObjects(); for(int i = 0; i < this.amountOfNewCables; i++) { generateCable(position.get(2 * i), position.get(2 * i + 1), position.get(2 * amountOfNewCables + i) == 1); } //Switches new Cable //Switches existing cable int count = 0; for(int i = 3 * amountOfNewCables; i < 3 * this.amountOfNewCables + this.amountOfExistingCables; i++) { generateEdgeFromIndexCable(cableList.get(count++), position.get(i) == 1); } //WildCards count = 0; for(int i = 3 * amountOfNewCables + amountOfExistingCables; i < position.size(); i++) { accessWildcards.get(count++).setState(position.get(i)); } for(HolonSwitch hSwitch: switchList) { hSwitch.setManualMode(true); hSwitch.setManualState(false); } control.calculateStateOnlyForCurrentTimeStep(); } /** * 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 model * @return */ protected List extractPositionAndAccess() { Model model = control.getModel(); resetAllList(); Category category = control.searchCategory("Wildcards"); if(category != null) { for(int count = 0; count < category.getObjects().size(); count++ ) { accessIntegerToWildcard.put(count + 1, category.getObjects().get(count)); } }else { console.println("No 'Wildcards' Category"); } List initialState = new ArrayList(); generateAccess(model.getObjectsOnCanvas(), null); addCables(model.getEdgesOnCanvas()); model.getEdgesOnCanvas().clear(); //New Cables for(int i = 0; i < this.amountOfNewCables; i++) { initialState.add(0); initialState.add(0); } //switch in new Cables for(int i = 0; i < this.amountOfNewCables; i++) { initialState.add(0); } //Switch in initial Cable cableSet.stream().forEach(indexCale -> initialState.add(0)); amountOfExistingCables = cableSet.size(); //wildcards for(int i = 0; i < accessWildcards.size(); i++) { initialState.add(0); } resetChain.add(initialState); //console.println(accessIntToObject.values().stream().map(hO -> hO.getName()).collect(Collectors.joining(", "))); //console.println(cableSet.stream().map(Object::toString).collect(Collectors.f(", "))); return initialState; } private void resetAllList() { //-->reset accessWildcards.clear(); this.countForAccessMap = 0; amountOfExistingCables = 0; accessIntToObject.clear(); accessObjectToInt.clear(); cableSet.clear(); cableList.clear(); accessGroupNode.clear(); accessIntegerToWildcard.clear(); addedIndexCable.clear(); switchList.clear(); accessSwitchGroupNode.clear(); edgeList.clear(); //<--- } /** * Method to extract the Informations recursively out of the Model. * @param nodes * @param positionToInit * @param timeStep */ private void generateAccess(List nodes, GroupNode groupnode) { for(AbstractCanvasObject aCps : nodes) { if(aCps instanceof HolonObject) { HolonObject hO = (HolonObject) aCps; accessIntToObject.put(++countForAccessMap, hO); accessObjectToInt.put(hO, countForAccessMap); if(hO.getName().contains("Wildcard")) { accessWildcards.add(new AccessWrapper(hO)); } if(groupnode != null) { accessGroupNode.put(hO, groupnode); } } if(aCps instanceof HolonSwitch) { HolonSwitch hSwitch = (HolonSwitch) aCps; accessIntToObject.put(++countForAccessMap, hSwitch); accessObjectToInt.put(hSwitch, countForAccessMap); if(groupnode != null) { accessGroupNode.put(hSwitch, groupnode); } } if(aCps instanceof Node) { Node node = (Node) aCps; accessIntToObject.put(++countForAccessMap, node); accessObjectToInt.put(node, countForAccessMap); if(groupnode != null) { accessGroupNode.put(node, groupnode); } } else if(aCps instanceof GroupNode) { generateAccess(((GroupNode)aCps).getNodes(), (GroupNode) aCps); } } } protected void resetWildcards() { this.accessWildcards.forEach(wrapper -> wrapper.resetState()); } /** * All Nodes have to be in the access map !! * @param cables */ private void addCables(List edges) { for (Edge edge : edges) { edge.setUnlimitedCapacity(true); edgeList.add(edge); //console.println("Cable from " + edge.getA().getName() + " to " + edge.getB().getName()); if(!accessObjectToInt.containsKey(edge.getA())) { console.println("Node A [" + edge.getA() + "] from Edge[" + edge + "] not exist"); continue; } else if (!accessObjectToInt.containsKey(edge.getB())) { console.println("Node B [" + edge.getB() + "]from Edge[" + edge + "] not exist"); continue; } IndexCable cable = new IndexCable(accessObjectToInt.get(edge.getA()), accessObjectToInt.get(edge.getB())); boolean success = cableSet.add(cable); if(success) { cableList.add(cable); } } } private void generateCable(int index0, int index1, boolean switchBetween) { //If cable isnt valid if(index0 == 0 || index1 == 0 || index0 == index1) { //console.println("Cable("+index1+","+index2+ ") isn't valid"); return; } IndexCable cable = new IndexCable(index0, index1); //if cable is in existing cables if(cableSet.contains(cable) || addedIndexCable.keySet().contains(cable)) { return; } generateEdgeFromIndexCable(cable, switchBetween); addedIndexCable.put(cable, cable.getLength()); } private void generateEdgeFromIndexCable(IndexCable cable, boolean switchBetween){ if(switchBetween) { //generate Switch AbstractCanvasObject fromObject = accessIntToObject.get(cable.first); AbstractCanvasObject toObject = accessIntToObject.get(cable.second); int middleX = (fromObject.getPosition().x + toObject.getPosition().x)/2; int middleY = (fromObject.getPosition().y + toObject.getPosition().y)/2; HolonSwitch newSwitch = new HolonSwitch("AddedSwitch"); newSwitch.setId(IdCounterElem.nextId()); newSwitch.setPosition(middleX, middleY); //If fromObject is in Group if(accessGroupNode.containsKey(fromObject)) { GroupNode groupnode = accessGroupNode.get(fromObject); groupnode.getNodes().add(newSwitch); accessSwitchGroupNode.put(newSwitch, groupnode); } else if(accessGroupNode.containsKey(toObject)) { GroupNode groupnode = accessGroupNode.get(toObject); groupnode.getNodes().add(newSwitch); accessSwitchGroupNode.put(newSwitch, groupnode); }else { control.getModel().getObjectsOnCanvas().add(newSwitch); } //else if toObject is in Group this.switchList.add(newSwitch); //Generate Cable From Object A To Switch Edge edge1 = new Edge(fromObject, newSwitch); edge1.setUnlimitedCapacity(true); control.getModel().getEdgesOnCanvas().add(edge1); edgeList.add(edge1); //Generate Cable From Object B To Switch Edge edge = new Edge(newSwitch, toObject); edge.setUnlimitedCapacity(true); control.getModel().getEdgesOnCanvas().add(edge); edgeList.add(edge); }else { Edge edge = new Edge(accessIntToObject.get(cable.first), accessIntToObject.get(cable.second)); edge.setUnlimitedCapacity(true); control.getModel().getEdgesOnCanvas().add(edge); edgeList.add(edge); } } private void removeAllAddedObjects() { control.getModel().getEdgesOnCanvas().removeAll(edgeList); addedIndexCable.clear(); //control.getModel().getObjectsOnCanvas().removeAll(switchList); for(HolonSwitch hSwitch: switchList) { if(this.accessSwitchGroupNode.containsKey(hSwitch)) { accessSwitchGroupNode.get(hSwitch).getNodes().remove(hSwitch); } else { control.getModel().getObjectsOnCanvas().remove(hSwitch); } } accessSwitchGroupNode.clear(); switchList.clear(); edgeList.clear(); } private String stringStatFromActualState() { if(dGroupNode != null) { //GetActualDecoratedGroupNode dGroupNode = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().get(dGroupNode.getModel()); int amountOfSupplier = dGroupNode.getAmountOfSupplier(); int amountOfConsumer = dGroupNode.getAmountOfConsumer(); int amountOfPassiv = dGroupNode.getAmountOfPassiv(); int amountOfObjects = amountOfSupplier + amountOfConsumer + amountOfPassiv; int unSuppliedConsumer = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.NOT_SUPPLIED); int partiallySuppliedConsumer = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.PARTIALLY_SUPPLIED); int suppliedConsumer = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.SUPPLIED); int overSuppliedConsumer = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.OVER_SUPPLIED); int activeElements = dGroupNode.getAmountOfAktiveElemntsFromHolonObjects(); int elements = dGroupNode.getAmountOfElemntsFromHolonObjects(); return "HolonObjects[" + " Producer: " + amountOfSupplier + "/" + amountOfObjects + "("+ (float)amountOfSupplier/(float)amountOfObjects * 100 + "%)" + " Unsupplied: " + unSuppliedConsumer + "/" + amountOfObjects + "("+ (float)unSuppliedConsumer/(float)amountOfObjects * 100 + "%)" + " PartiallySupplied: " + partiallySuppliedConsumer + "/" + amountOfObjects + "("+ (float)partiallySuppliedConsumer/(float)amountOfObjects * 100 + "%)" + " Supplied: " + suppliedConsumer + "/" + amountOfObjects + "("+ (float)suppliedConsumer/(float)amountOfObjects * 100 + "%)" + " Passiv: " + overSuppliedConsumer + "/" + amountOfObjects + "("+ (float)overSuppliedConsumer/(float)amountOfObjects * 100 + "%)" + "]" + " HolonElemnts[" + " Active: " + activeElements + "/" + elements + "("+ (float)activeElements/(float)elements * 100 + "%)" + "]"; } DecoratedState state = control.getSimManager().getActualDecorState(); int amountOfSupplier = 0, amountOfConsumer = 0, amountOfPassiv = 0, unSuppliedConsumer = 0, partiallySuppliedConsumer = 0, suppliedConsumer = 0, overSuppliedConsumer = 0; int activeElements = 0, amountOfelements = 0; int totalConsumption = 0, totalProduction = 0; for(DecoratedNetwork net : state.getNetworkList()) { amountOfConsumer += net.getAmountOfConsumer(); amountOfSupplier += net.getAmountOfSupplier(); amountOfPassiv += net.getAmountOfPassiv(); unSuppliedConsumer += net.getAmountOfConsumerWithState(HolonObjectState.NOT_SUPPLIED); partiallySuppliedConsumer += net.getAmountOfConsumerWithState(HolonObjectState.PARTIALLY_SUPPLIED); suppliedConsumer += net.getAmountOfConsumerWithState(HolonObjectState.SUPPLIED); overSuppliedConsumer += net.getAmountOfConsumerWithState(HolonObjectState.OVER_SUPPLIED); amountOfelements += net.getAmountOfElements(); activeElements += net.getAmountOfActiveElements(); totalConsumption += net.getTotalConsumption(); totalProduction += net.getTotalProduction(); } int amountOfObjects = amountOfSupplier + amountOfConsumer + amountOfPassiv; int difference = Math.abs(totalProduction - totalConsumption); int amountHolons = state.getNetworkList().size(); int amountSwitch = state.getDecoratedSwitches().size(); int amountActiveSwitch = (int)state.getDecoratedSwitches().stream().filter(dswitch -> (dswitch.getState() == SwitchState.Closed)).count(); int addedSwitches = calculateAmountOfAddedSwitches(); double addedCableMeters = addedCableMeter(); double wildcardCost = TopologieObjectiveFunction.calculateWildcardCost(state); double cableCost = TopologieObjectiveFunction.calculateWildcardCost(state); double switchCost = TopologieObjectiveFunction.calculateWildcardCost(state); double totalCost = wildcardCost + cableCost + switchCost; DoubleSummaryStatistics overStat = state.getNetworkList().stream().flatMap(net -> { return net.getConsumerList().stream().filter(con -> con.getState() == HolonObjectState.OVER_SUPPLIED); }).mapToDouble(con -> con.getSupplyBarPercentage()).summaryStatistics(); DoubleSummaryStatistics partiallyStat = state.getNetworkList().stream().flatMap(net -> { return net.getConsumerList().stream().filter(con -> con.getState() == HolonObjectState.PARTIALLY_SUPPLIED); }).mapToDouble(con -> con.getSupplyBarPercentage()).summaryStatistics(); return "HolonObjects[" + " Passiv: " + percentage(amountOfPassiv, amountOfObjects) + " Producer: " + percentage(amountOfSupplier, amountOfObjects) + " Consumer: " + percentage(amountOfConsumer, amountOfObjects) + " Unsupplied: " + percentage(unSuppliedConsumer, amountOfConsumer) + " PartiallySupplied: " + percentage(partiallySuppliedConsumer, amountOfObjects) + " with SupplyPercentage(Min: " + partiallyStat.getMin() + " Max: "+ partiallyStat.getMax() + " Average: " +partiallyStat.getAverage() + ")" + " Supplied: " + percentage(suppliedConsumer, amountOfConsumer) + " Over: " + percentage(overSuppliedConsumer, amountOfConsumer) + " with SupplyPercentage(Min: " + overStat.getMin() + " Max: "+ overStat.getMax() + " Average: " + overStat.getAverage() + ")" + "]" + " HolonElemnts[" + " Active: " + percentage(activeElements, amountOfelements) + "]" + " activeSwitches:" + percentage(amountActiveSwitch,amountSwitch) + " Holons: " + amountHolons + " totalConsumption: " + totalConsumption + " totalProduction: " + totalProduction + " difference: " + difference + " Topologie[" + " addedCableMeters:" + addedCableMeters + " addedSwitches: " + addedSwitches + " totalCost: " + totalCost + "(" + " wildcardCost: " + wildcardCost + " cableCost: " + cableCost + " switchCost: " + switchCost + ")]" ; } private String percentage(int actual, int max) { return actual + "/" + max + "("+ (float)actual/(float)max * 100 + "%)"; } @Override public JPanel getPanel() { return content; } @Override public void setController(Control control) { this.control = control; } // | New Cable | Switches | Wildcards | //return index: | countForAccessMap | 1 | accessWildcards.size()| public int getMaximumIndexObjects(int index) { int maximumIndex = -1; //New Cables if(index < 2 * amountOfNewCables) { maximumIndex = this.countForAccessMap; } //Switches in existing and in new Cables else if (index < 3 * amountOfNewCables + this.amountOfExistingCables) { maximumIndex = 1; } //wildcards else { maximumIndex = this.accessIntegerToWildcard.size(); } return maximumIndex; } private class RunProgressBar{ //progressbar private JProgressBar progressBar = new JProgressBar(); private int count = 0; private boolean isActive = false; public void step() { if(isActive) progressBar.setValue(count++); } public void start() { progressBar.setIndeterminate(false); count = 0; isActive = true; progressBar.setValue(0); progressBar.setMaximum(getProgressBarMaxCount()); } public void cancel() { isActive = false; progressBar.setIndeterminate(true); } public void finishedCancel() { progressBar.setIndeterminate(false); progressBar.setValue(0); } public JProgressBar getJProgressBar(){ return progressBar; } } protected abstract int getProgressBarMaxCount(); protected abstract String algoInformationToPrint(); protected abstract String plottFileName(); public class Printer{ private JFileChooser fileChooser = new JFileChooser(); private BufferedWriter out; public Printer(String filename){ fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); fileChooser.setSelectedFile(new File(filename)); } public void openStream() { File file = fileChooser.getSelectedFile(); try { file.createNewFile(); out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(file, true), "UTF-8")); } catch (IOException e) { System.out.println(e.getMessage()); } } public void println(String stringToPrint) { try { out.write(stringToPrint); out.newLine(); } catch (IOException e) { System.out.println(e.getMessage()); } } public void closeStream() { try { out.close(); } catch (IOException e) { System.out.println(e.getMessage()); } } } /** * A Wrapper Class to access wildcards */ private class AccessWrapper { int state = 0; HolonObject wildcard; public AccessWrapper(HolonObject wildcard) { this.wildcard = wildcard; } public void setState(int state) { if(this.state != state) { this.state = state; if(state > 0) { wildcard.getElements().clear(); HolonObject hO = (HolonObject)accessIntegerToWildcard.get(state); if(hO == null) { console.println("null set state(" + state + ")"); }else { if(hO.getName().contains(":")) { wildcard.setName("Wildcard" + hO.getName().substring(hO.getName().lastIndexOf(":"))); }else { wildcard.setName("Wildcard"); } wildcard.getElements().addAll(hO.getElements()); wildcard.setImage(hO.getImage()); } }else { resetState(); } } } public void resetState() { state = 0; wildcard.setName("Wildcard"); wildcard.setImage("/Images/home-2.png"); wildcard.getElements().clear(); } public String toString() { return wildcard + "have state: " + state; } } public class Individual { public double fitness; public List position; public Individual(){}; /** * Copy Constructor */ public Individual(Individual c){ position = c.position.stream().collect(Collectors.toList()); fitness = c.fitness; } } protected class ParameterStepping{ boolean useThisParameter = false; String paramaterName; private int count = 0; int stepps; T stepSize; T startValue; Consumer setter; Supplier getter; BiFunction multyply; BiFunction add; ParameterStepping(Consumer setter, Supplier getter, BiFunction add, BiFunction multyply, T stepSize, int stepps){ this.setter = setter; this.getter = getter; this.multyply = multyply; this.add = add; this.stepSize = stepSize; this.stepps = stepps; } void init() { startValue = getter.get(); } boolean canUpdate() { return count < stepps; } void update(){ if(canUpdate()) { setter.accept(add.apply(startValue, multyply.apply(count + 1, stepSize))); count ++; } } void reset() { setter.accept(startValue); count = 0; } } public class IndexCable{ public final Integer first; public final Integer second; public IndexCable(Integer first, Integer second) { if(first.compareTo(second) == 0) { throw new IllegalArgumentException("(" + first + "==" + second + ")" + "Two ends of the cable are at the same Object"); } else if(first.compareTo(second) < 0) { this.first = first; this.second = second; }else { this.first = second; this.second = first; } } @Override public boolean equals(Object o) { if (!(o instanceof IndexCable)) { return false; } IndexCable p = (IndexCable) o; return Objects.equals(p.first, first) && Objects.equals(p.second, second); } @Override public int hashCode() { return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode()); } @Override public String toString() { return "{" + first + "," + second + "}"; } public double getLength() { return accessIntToObject.get(first).getPosition().Distance(accessIntToObject.get(second).getPosition()); } } }