package api; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.image.BufferedImage; 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.LinkedList; import java.util.List; import java.util.Locale; 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.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JFormattedTextField; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.text.NumberFormatter; import classes.AbstractCpsObject; import classes.CpsUpperNode; import classes.Flexibility; import classes.HolonElement; import classes.HolonObject; import classes.HolonSwitch; import classes.HolonElement.Priority; import ui.controller.Control; import ui.controller.FlexManager.FlexState; import ui.controller.FlexManager.FlexWrapper; 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 AlgorithmFrameworkFlex implements AddOn{ //Algo protected int rounds = 1; //Panel private JPanel content = new JPanel(); protected Console console = new Console(); private JPanel borderPanel = new JPanel(); //Settings groupNode private DecoratedGroupNode dGroupNode = null; //access private ArrayList access; LinkedList> resetChain = new LinkedList>(); 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()); private Printer logPrinter = new Printer("logFile.txt"); protected List runList = new LinkedList(); //Parameter @SuppressWarnings("rawtypes") LinkedList parameterSteppingList= new LinkedList(); protected boolean useStepping = false; public AlgorithmFrameworkFlex(){ 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)); //Add rounds } private JPanel createOptionPanel() { JPanel optionPanel = new JPanel(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(createParameterPanel()); scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter")); optionPanel.add(scrollPane, BorderLayout.CENTER); optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END); return optionPanel; } private Component createParameterPanel() { JPanel parameterPanel = new JPanel(null); parameterPanel.setPreferredSize(new Dimension(510,300)); borderPanel.setLayout(new BoxLayout(borderPanel, BoxLayout.PAGE_AXIS)); addIntParameter("Rounds", rounds, intInput -> rounds = intInput, () -> rounds, 1); JScrollPane scrollPane = new JScrollPane(borderPanel); scrollPane.setBounds(10, 0, 850, 292); scrollPane.setBorder(BorderFactory.createEmptyBorder()); parameterPanel.add(scrollPane); JButton selectGroupNodeButton = new JButton("Select GroupNode"); selectGroupNodeButton.setBounds(900, 0, 185, 30); selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode()); parameterPanel.add(selectGroupNodeButton); JProgressBar progressBar = runProgressbar.getJProgressBar(); progressBar.setBounds(900, 35, 185, 20); progressBar.setStringPainted(true); parameterPanel.add(progressBar); JCheckBox useElements = new JCheckBox("Elements"); useElements.setSelected(algoUseElements); useElements.setBounds(900, 70, 185, 20); useElements.addActionListener(actionEvent -> algoUseElements = useElements.isSelected()); parameterPanel.add(useElements); JCheckBox useSwitches = new JCheckBox("Switches"); useSwitches.setSelected(algoUseSwitches); useSwitches.setBounds(900, 90, 185, 20); useSwitches.addActionListener(actionEvent -> algoUseSwitches = useSwitches.isSelected()); parameterPanel.add(useSwitches); JCheckBox useFlexes = new JCheckBox("Flexibilities"); useFlexes.setSelected(algoUseFlexes); useFlexes.setBounds(900, 110, 185, 20); useFlexes.addActionListener(actionEvent -> algoUseFlexes = useFlexes.isSelected()); parameterPanel.add(useFlexes); return parameterPanel; } private JPanel createButtonPanel() { JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 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 -> { Runnable task = () -> run(); runThread = new Thread(task); runThread.start(); }); buttonPanel.add(runButton); return buttonPanel; } //ParameterImports //int protected void addIntParameter(String parameterName, int parameterValue, Consumer setter, Supplier getter) { this.addIntParameter(parameterName, parameterValue, setter, getter, 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, parameterMinValue, Integer.MAX_VALUE); } protected void addIntParameter(String parameterName, int parameterValue, Consumer setter, Supplier getter, 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); }); borderPanel.add(singleParameterPanel); } //double protected void addDoubleParameter(String parameterName, double parameterValue, Consumer setter, Supplier getter) { this.addDoubleParameter(parameterName, parameterValue, setter, getter, 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, parameterMinValue, Double.MAX_VALUE); } protected void addDoubleParameter(String parameterName, double parameterValue, Consumer setter, Supplier getter, 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); }); borderPanel.add(singleParameterPanel); } //boolean protected void addBooleanParameter(String parameterName, boolean parameterValue, Consumer setter){ 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()); JCheckBox useGroupNodeCheckBox = new JCheckBox(); useGroupNodeCheckBox.setSelected(parameterValue); useGroupNodeCheckBox.addActionListener(actionEvent -> setter.accept(useGroupNodeCheckBox.isSelected())); 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 fitness() { if(runThread.isAlive()) { console.println("Run have to be cancelled First."); return; } double currentFitness = evaluatePosition(extractPositionAndAccess()); resetChain.removeLast(); console.println("Actual Fitnessvalue: " + currentFitness); } private void selectGroupNode() { Object[] possibilities = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().values().stream().map(aCps -> new Handle(aCps)).toArray(); @SuppressWarnings("unchecked") Handle selected = (Handle) JOptionPane.showInputDialog(content, "Select GroupNode:", "GroupNode?", JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , possibilities, ""); if(selected != null) { console.println("Selected: " + selected); dGroupNode = selected.object; } } protected double evaluatePosition(List positionToEvaluate, String logString) { double objectiveFunction = evaluatePosition(positionToEvaluate); String toPrint = "oF: " + objectiveFunction + " " + logString; logPrinter.openStream(); logPrinter.println(toPrint); logPrinter.closeStream(); return objectiveFunction; } protected double evaluatePosition(List positionToEvaluate) { runProgressbar.step(); // long startTime = System.currentTimeMillis(), endTime; control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration()); // execution time critical // endTime = System.currentTimeMillis(); // console.print(" a:" + (endTime - startTime)); // startTime = endTime; setState(positionToEvaluate); // execution time critical control.calculateStateOnlyForCurrentTimeStep(); DecoratedState actualstate = control.getSimManager().getActualDecorState(); double result = evaluateState(actualstate); return result; } protected abstract double evaluateState(DecoratedState actualstate); 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(); } 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()); console.println("BitLength: " + access.size()); resetChain.removeLast(); runPrinter.openStream(); runPrinter.println(""); runPrinter.println(algoInformationToPrint()); console.println(algoInformationToPrint()); runPrinter.closeStream(); runProgressbar.start(); Individual runBest = new Individual(); runBest.fitness = Double.MAX_VALUE; for(int r = 0; r < rounds; r++) { startTimer(); Individual roundBest = executeAlgo(); if(cancel)return; long executionTime = printElapsedTime(); runPrinter.openStream(); runPrinter.println(runList.stream().map(Object::toString).collect(Collectors.joining(", "))); runPrinter.println(stringStatFromActualState()); runPrinter.println("Result: " + roundBest.fitness + " ExecutionTime:" + executionTime); runPrinter.closeStream(); resetState(); if(roundBest.fitness < runBest.fitness) runBest = roundBest; } control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration()); this.extractPositionAndAccess(); setState(runBest.position); updateVisual(); console.println("Start: " + startFitness); console.println("AlgoResult: " + runBest.fitness); if(this.algoUseFlexes)calculateAndPrintFlexInfos(control.getSimManager().getActualDecorState()); } private void calculateAndPrintFlexInfos(DecoratedState state) { int amountOfUsedFlex = 0; int amountOfFlex = state.getFlexManager().getAllFlexWrapper().size(); float cost = 0; int consumingFlex = 0; float consumingFlexEnergy = 0.0f; int producingFlex = 0; float producingFlexEnergy = 0.0f; int maxCooldown = 0; int amountEssential = 0; int amountHigh = 0; int amountMedium = 0; int amountLow = 0; for(FlexWrapper flexWrapper :state.getFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)) { amountOfUsedFlex++; cost += flexWrapper.getFlex().cost; float energy = flexWrapper.getFlex().bringtmir(); if(energy < 0) { consumingFlex++; consumingFlexEnergy += -energy; }else { producingFlex++; producingFlexEnergy += energy; } if(flexWrapper.getFlex().getCooldown() > maxCooldown) maxCooldown = flexWrapper.getFlex().getCooldown(); switch(flexWrapper.getFlex().getElement().getPriority()) { case Essential: amountEssential++; break; case High: amountHigh++; break; case Low: amountLow++; break; case Medium: amountMedium++; break; default: break; } } //Total Flexibilities: //Used Flexibilities: console.println("Used Flex [" + amountOfUsedFlex + "/" + amountOfFlex + "]"); //Consuming Flexibilities: console.println(consumingFlex + " consuimg flexibilities that consumed " + consumingFlexEnergy + "Energy."); //Producing Flexibilities console.println(producingFlex + " producing flexibilities that produce " + producingFlexEnergy + "Energy."); console.println("Flex in use:\t" + "Low= " + amountLow + "\tMedium= " + amountMedium + "\tHigh= " + amountHigh + "\tEssential= " + amountEssential); //Total cost: console.println("Total Cost: "+ cost); //Longest Cooldown console.println("Max Cooldown: "+ maxCooldown); // } 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()); control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration()); 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() { control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration()); setState(resetChain.getLast()); } /** * Sets the State out of the given position for calculation or to show the user. * @param position */ private void setState(List position) { int i = 0; for(Boolean bool: position) { access.get(i++).setState(bool); } } /** * 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(); access= new ArrayList(); List initialState = new ArrayList(); rollOutNodes((dGroupNode != null)? dGroupNode.getModel().getNodes() :model.getObjectsOnCanvas(), initialState, model.getCurIteration()); resetChain.add(initialState); if(algoUseFlexes) { for(FlexWrapper flex :control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.OFFERED)){ access.add(new AccessWrapper(flex.getFlex())); initialState.add(false); } for(FlexWrapper flex :control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)){ access.add(new AccessWrapper(flex.getFlex())); initialState.add(true); } } //console.println(access.stream().map(Object::toString).collect(Collectors.joining(", "))); return initialState; } /** * Method to extract the Informations recursively out of the Model. * @param nodes * @param positionToInit * @param timeStep */ private void rollOutNodes(List nodes, List positionToInit, int timeStep) { for(AbstractCpsObject aCps : nodes) { if (aCps instanceof HolonObject && algoUseElements) { for (HolonElement hE : ((HolonObject) aCps).getElements()) { positionToInit.add(hE.isActive()); access.add(new AccessWrapper(hE)); } } else if (aCps instanceof HolonSwitch&& algoUseSwitches) { HolonSwitch sw = (HolonSwitch) aCps; positionToInit.add(sw.getState(timeStep)); access.add(new AccessWrapper(sw)); } else if(aCps instanceof CpsUpperNode) { rollOutNodes(((CpsUpperNode)aCps).getNodes(), positionToInit ,timeStep ); } } } 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); List flexActiveList = control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE).stream().map(flex -> flex.getFlex()).collect(Collectors.toList()); int amountActiveEssential = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Essential).count(); int amountActiveHigh = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.High).count(); int amountActiveMedium = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Medium).count(); int amountActiveLow = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Low).count(); int amountActiveFlexibilities = amountActiveEssential + amountActiveHigh + amountActiveMedium + amountActiveLow; int amountHolons = state.getNetworkList().size(); int amountSwitch = state.getDecoratedSwitches().size(); int amountActiveSwitch = (int)state.getDecoratedSwitches().stream().filter(dswitch -> (dswitch.getState() == SwitchState.Closed)).count(); return "HolonObjects[" + " Passiv: " + percentage(amountOfPassiv, amountOfObjects) + " Producer: " + percentage(amountOfSupplier, amountOfObjects) + " Consumer: " + percentage(amountOfConsumer, amountOfObjects) + " Unsupplied: " + percentage(unSuppliedConsumer, amountOfConsumer) + " PartiallySupplied: " + percentage(partiallySuppliedConsumer, amountOfObjects) + " Supplied: " + percentage(suppliedConsumer, amountOfConsumer) + " Over: " + percentage(overSuppliedConsumer, amountOfConsumer) + "]" + " HolonElemnts[" + " Active: " + percentage(activeElements, amountOfelements) + "]" + "Flexibilities_active[" + " Essential: " + percentage(amountActiveEssential, amountActiveFlexibilities) + " High: " + percentage(amountActiveHigh, amountActiveFlexibilities) + " Medium: " + percentage(amountActiveMedium, amountActiveFlexibilities) + " Low: " + percentage(amountActiveLow, amountActiveFlexibilities) + "]" + " activeSwitches:" + percentage(amountActiveSwitch,amountSwitch) + " Holons: " + amountHolons + " totalConsumption: " + totalConsumption + " totalProduction: " + totalProduction + " difference: " + difference; } 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; } 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 for Access HolonElement and HolonSwitch in one Element and not have to split the List. */ private class AccessWrapper { public static final int HOLONELEMENT = 0; public static final int SWITCH = 1; public static final int FLEXIBILITY = 2; private int type; private HolonSwitch hSwitch; private HolonElement hElement; private Flexibility flex; public AccessWrapper(HolonSwitch hSwitch){ type = SWITCH; this.hSwitch = hSwitch; } public AccessWrapper(HolonElement hElement){ type = HOLONELEMENT; this.hElement = hElement; } public AccessWrapper(Flexibility flex){ type = FLEXIBILITY; this.flex = flex; } public void setState(boolean state) { switch(type) { case HOLONELEMENT: hElement.setActive(state); break; case SWITCH: hSwitch.setManualMode(true); hSwitch.setManualState(state); break; case FLEXIBILITY: if(state) { control.getSimManager().getActualFlexManager().orderFlex(flex); } break; default: } } public String typeString() { switch(type) { case HOLONELEMENT: return "HOLONELEMENT"; case SWITCH: return "SWITCH"; case FLEXIBILITY: return "FLEXIBILITY"; default: return "unknown"; } } public String toString() { return "[" + typeString() + "]"; } } /** * To create Random and maybe switch the random generation in the future. */ protected static class Random{ private static java.util.Random random = new java.util.Random(); /** * True or false * @return the random boolean. */ public static boolean nextBoolean(){ return random.nextBoolean(); } /** * Between 0.0(inclusive) and 1.0 (exclusive) * @return the random double. */ public static double nextDouble() { return random.nextDouble(); } /** * Random Int in Range [min;max[ with UniformDistirbution * @param min * @param max * @return */ public static int nextIntegerInRange(int min, int max) { int result = min; try { result = min + random.nextInt(max - min); }catch(java.lang.IllegalArgumentException e){ System.err.println("min : " + min + " max : " + max); System.err.println("max should be more then min"); } return result; } } private class Handle{ public T object; Handle(T object){ this.object = object; } public String toString() { return object.toString(); } } 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; } } }