|
@@ -1,1364 +1,1365 @@
|
|
|
-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.DoubleSummaryStatistics;
|
|
|
-import java.util.HashMap;
|
|
|
-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.JComboBox;
|
|
|
-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 algorithm.objectiveFunction.ObjectiveFunctionByCarlos;
|
|
|
-import algorithm.objectiveFunction.SwitchObjectiveFunction;
|
|
|
-import classes.AbstractCanvasObject;
|
|
|
-import classes.GroupNode;
|
|
|
-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;
|
|
|
-import utility.ImageImport;
|
|
|
-import utility.StringFormat;
|
|
|
-
|
|
|
-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<AccessWrapper> access;
|
|
|
- private HashMap<HolonObject, AccessWrapper> accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
|
|
|
- LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
|
|
|
- boolean algoUseElements = false, algoUseSwitches = true, algoUseFlexes = true, algoUseKillSwitch = 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<Double> runList = new LinkedList<Double>();
|
|
|
- private RunAverage avg = new RunAverage();
|
|
|
-
|
|
|
- //Parameter
|
|
|
- @SuppressWarnings("rawtypes")
|
|
|
- LinkedList<ParameterStepping> parameterSteppingList= new LinkedList<ParameterStepping>();
|
|
|
- protected boolean useStepping = false;
|
|
|
-
|
|
|
- //Email
|
|
|
- private boolean useEmailNotification = false;
|
|
|
-
|
|
|
-
|
|
|
- //ObjectiveFunction
|
|
|
- enum ObjectiveFunction {Normal, Switch};
|
|
|
- ObjectiveFunction evaluationFunction = ObjectiveFunction.Normal;
|
|
|
-
|
|
|
- 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));
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- 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);
|
|
|
-
|
|
|
- JCheckBox useKillSwitches = new JCheckBox("KillSwitch");
|
|
|
- useKillSwitches.setSelected(algoUseFlexes);
|
|
|
- useKillSwitches.setBounds(900, 130, 185, 20);
|
|
|
- useKillSwitches.addActionListener(actionEvent ->
|
|
|
- {
|
|
|
- cancel();
|
|
|
- reset();
|
|
|
- algoUseKillSwitch = useKillSwitches.isSelected();
|
|
|
- });
|
|
|
- parameterPanel.add(useKillSwitches);
|
|
|
-
|
|
|
- String[] objectiveFunctionStrings = { "Normal", "Switch"};
|
|
|
- JLabel fitnessLabel = new JLabel("FitnessFunction:");
|
|
|
- fitnessLabel.setBounds(910, 160, 90, 20);
|
|
|
- parameterPanel.add(fitnessLabel);
|
|
|
- JComboBox<String> ofBox = new JComboBox<String>(objectiveFunctionStrings);
|
|
|
- ofBox.addActionListener(actionEvent ->
|
|
|
- {
|
|
|
- boolean pickNormal = ((String)ofBox.getSelectedItem()).equals("Normal");
|
|
|
- evaluationFunction = pickNormal?ObjectiveFunction.Normal:ObjectiveFunction.Switch;
|
|
|
- });
|
|
|
- ofBox.setBounds(1000, 160, 70, 20);
|
|
|
- parameterPanel.add(ofBox);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- JCheckBox emailNotificationCheckbox = new JCheckBox("EmailNotification");
|
|
|
- emailNotificationCheckbox.setSelected(this.useEmailNotification);
|
|
|
- emailNotificationCheckbox.setBounds(900, 200, 130, 20);
|
|
|
- emailNotificationCheckbox.addActionListener(actionEvent -> useEmailNotification = emailNotificationCheckbox.isSelected());
|
|
|
- parameterPanel.add(emailNotificationCheckbox);
|
|
|
-
|
|
|
- JButton emailSettingsButton = new JButton("", new ImageIcon(ImageImport.loadImage("/Images/settingsIcon.png", 16,16)));
|
|
|
- emailSettingsButton.setBounds(1030, 200, 20, 20);
|
|
|
- emailSettingsButton.addActionListener(event -> {
|
|
|
- EmailNotification.OpenEmailSettings(content);
|
|
|
- });
|
|
|
- parameterPanel.add(emailSettingsButton);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- 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<Integer> setter, Supplier<Integer> getter) {
|
|
|
- this.addIntParameter(parameterName, parameterValue, setter, getter, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
|
|
- }
|
|
|
-
|
|
|
- protected void addIntParameter(String parameterName, int parameterValue, Consumer<Integer> setter, Supplier<Integer> getter, int parameterMinValue) {
|
|
|
- this.addIntParameter(parameterName, parameterValue, setter, getter, parameterMinValue, Integer.MAX_VALUE);
|
|
|
- }
|
|
|
-
|
|
|
- protected void addIntParameter(String parameterName, int parameterValue, Consumer<Integer> setter, Supplier<Integer> 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<Integer> intParameterStepping = new ParameterStepping<Integer>(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<Double> setter, Supplier<Double> getter) {
|
|
|
- this.addDoubleParameter(parameterName, parameterValue, setter, getter, Double.MIN_VALUE, Double.MAX_VALUE);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- protected void addDoubleParameter(String parameterName, double parameterValue, Consumer<Double> setter, Supplier<Double> getter, double parameterMinValue) {
|
|
|
- this.addDoubleParameter(parameterName, parameterValue, setter, getter, parameterMinValue, Double.MAX_VALUE);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- protected void addDoubleParameter(String parameterName, double parameterValue, Consumer<Double> setter, Supplier<Double> 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<Double> doubleParameterStepping = new ParameterStepping<Double>(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<Boolean> 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<DecoratedGroupNode>(aCps)).toArray();
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- Handle<DecoratedGroupNode> selected = (Handle<DecoratedGroupNode>) 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<Boolean> positionToEvaluate) {
|
|
|
- runProgressbar.step();
|
|
|
- setState(positionToEvaluate); // execution time critical
|
|
|
- DecoratedState actualstate = control.getSimManager().getActualDecorState();
|
|
|
- double result = evaluateState(actualstate);
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- private double evaluateState(DecoratedState actualstate) {
|
|
|
- switch(this.evaluationFunction) {
|
|
|
- case Switch:
|
|
|
- return SwitchObjectiveFunction.getFitnessValueForState(actualstate);
|
|
|
- case Normal:
|
|
|
- default:
|
|
|
- return ObjectiveFunctionByCarlos.getFitnessValueForState(actualstate);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private void run() {
|
|
|
- cancel = false;
|
|
|
- control.guiDisable(true);
|
|
|
- runPrinter.openStream();
|
|
|
- runPrinter.println("");
|
|
|
- runPrinter.println("Start:" + stringStatFromRunValues(getRunValuesFromActualState()));
|
|
|
- runPrinter.closeStream();
|
|
|
- if(this.useStepping) {
|
|
|
- initParameterStepping();
|
|
|
- do {
|
|
|
- executeAlgoWithParameter();
|
|
|
- if(cancel) break;
|
|
|
- resetState();
|
|
|
- }while(updateOneParameter());
|
|
|
- resetParameterStepping();
|
|
|
- }else {
|
|
|
- executeAlgoWithParameter();
|
|
|
-
|
|
|
- }
|
|
|
- updateVisual();
|
|
|
- runProgressbar.finishedCancel();
|
|
|
- control.guiDisable(false);
|
|
|
- if(this.useEmailNotification && !cancel) {
|
|
|
- EmailNotification.sendEmail(this.getClass().getName() + " finished", "Execution done.");
|
|
|
- }
|
|
|
- }
|
|
|
- @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<ParameterStepping> 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(algoInformationToPrint());
|
|
|
- console.println(algoInformationToPrint());
|
|
|
- runPrinter.closeStream();
|
|
|
- runProgressbar.start();
|
|
|
- Individual runBest = new Individual();
|
|
|
- runBest.fitness = Double.MAX_VALUE;
|
|
|
- this.avg = new RunAverage();
|
|
|
- for(int r = 0; r < rounds; r++)
|
|
|
- {
|
|
|
- startTimer();
|
|
|
- Individual roundBest = executeAlgo();
|
|
|
- if(cancel)return;
|
|
|
- long executionTime = printElapsedTime();
|
|
|
- setState(roundBest.position);
|
|
|
- runPrinter.openStream();
|
|
|
- runPrinter.println(runList.stream().map(value -> StringFormat.doubleFixedPlaces(2,value)).collect(Collectors.joining(", ")));
|
|
|
- RunValues val = getRunValuesFromActualState();
|
|
|
- val.result = roundBest.fitness;
|
|
|
- val.executionTime = executionTime;
|
|
|
- avg.addRun(val);
|
|
|
- runPrinter.println("Result: " + StringFormat.doubleFixedPlaces(2,roundBest.fitness) + " ExecutionTime:" + executionTime + " " + stringStatFromRunValues(val));
|
|
|
- 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: " + StringFormat.doubleFixedPlaces(2,startFitness));
|
|
|
- console.println("AlgoResult: " + StringFormat.doubleFixedPlaces(2,runBest.fitness));
|
|
|
- if(this.algoUseFlexes)calculateAndPrintFlexInfos(control.getSimManager().getActualDecorState());
|
|
|
- runPrinter.openStream();
|
|
|
- if(rounds > 1) {
|
|
|
- RunValues avgRun = avg.getAverage();
|
|
|
-
|
|
|
- runPrinter.println("Average.Result: " + StringFormat.doubleFixedPlaces(2, avgRun.result) + " Average.ExecutionTime:" + avgRun.executionTime + " " + this.stringStatFromRunValues(avg.getAverage(), "Average."));
|
|
|
- }
|
|
|
- runPrinter.println("");
|
|
|
- runPrinter.closeStream();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- 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());
|
|
|
- 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() {
|
|
|
- setState(resetChain.getLast());
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Sets the State out of the given position for calculation or to show the user.
|
|
|
- * @param position
|
|
|
- */
|
|
|
- private void setState(List<Boolean> position) {
|
|
|
- control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration());
|
|
|
- int i = 0;
|
|
|
- for(Boolean bool: position) {
|
|
|
- access.get(i++).setState(bool);
|
|
|
- }
|
|
|
- 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<Boolean> extractPositionAndAccess() {
|
|
|
- Model model = control.getModel();
|
|
|
- this.accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
|
|
|
- access= new ArrayList<AccessWrapper>();
|
|
|
- List<Boolean> initialState = new ArrayList<Boolean>();
|
|
|
- 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)){
|
|
|
- //flex.getFlex().getElement().parentObject;
|
|
|
- AccessWrapper killSwitchAccess = this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getFlex().getElement().parentObject): null;;
|
|
|
- access.add(new AccessWrapper(flex.getFlex(), killSwitchAccess));
|
|
|
- initialState.add(false);
|
|
|
- }
|
|
|
- for(FlexWrapper flex :control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)){
|
|
|
- AccessWrapper killSwitchAccess = this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getFlex().getElement().parentObject): null;
|
|
|
- access.add(new AccessWrapper(flex.getFlex(), killSwitchAccess));
|
|
|
- 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<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
|
|
|
- for(AbstractCanvasObject aCps : nodes) {
|
|
|
- if (aCps instanceof HolonObject) {
|
|
|
- HolonObject hObject = (HolonObject) aCps;
|
|
|
- AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
|
|
|
- if(this.algoUseKillSwitch) {
|
|
|
- positionToInit.add(false);
|
|
|
- access.add(killSwitchAccess);
|
|
|
- accessKillSwitch.put(hObject, killSwitchAccess);
|
|
|
- }
|
|
|
- if(this.algoUseElements) {
|
|
|
- for (HolonElement hE : hObject.getElements()) {
|
|
|
- positionToInit.add(hE.isActive());
|
|
|
- access.add(new AccessWrapper(hE, killSwitchAccess));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if (aCps instanceof HolonSwitch&& algoUseSwitches) {
|
|
|
- HolonSwitch sw = (HolonSwitch) aCps;
|
|
|
- positionToInit.add(sw.getState(timeStep));
|
|
|
- access.add(new AccessWrapper(sw));
|
|
|
- }
|
|
|
- else if(aCps instanceof GroupNode) {
|
|
|
- rollOutNodes(((GroupNode)aCps).getNodes(), positionToInit ,timeStep );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private RunValues getRunValuesFromActualState() {
|
|
|
- RunValues val = new RunValues();
|
|
|
- if(dGroupNode != null)
|
|
|
- {
|
|
|
- //GetActualDecoratedGroupNode
|
|
|
- dGroupNode = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().get(dGroupNode.getModel());
|
|
|
- val.producer = dGroupNode.getAmountOfSupplier();
|
|
|
- val.consumer = dGroupNode.getAmountOfConsumer();
|
|
|
- val.passiv = dGroupNode.getAmountOfPassiv();
|
|
|
- val.objects = val.producer + val.consumer + val.passiv;
|
|
|
- val.unsupplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.NOT_SUPPLIED);
|
|
|
- val.partiallySupplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.PARTIALLY_SUPPLIED);
|
|
|
- val.supplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.SUPPLIED);
|
|
|
- val.overSupplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.OVER_SUPPLIED);
|
|
|
-
|
|
|
-
|
|
|
- val.activeElements = dGroupNode.getAmountOfAktiveElemntsFromHolonObjects();
|
|
|
- val.elements = dGroupNode.getAmountOfElemntsFromHolonObjects();
|
|
|
- //TODO what should be printed happen when only groupNode are selected
|
|
|
- }
|
|
|
- DecoratedState state = control.getSimManager().getActualDecorState();
|
|
|
- for(DecoratedNetwork net : state.getNetworkList()) {
|
|
|
- val.consumer += net.getAmountOfConsumer();
|
|
|
- val.producer += net.getAmountOfSupplier();
|
|
|
- val.passiv += net.getAmountOfPassiv();
|
|
|
- val.unsupplied += net.getAmountOfConsumerWithState(HolonObjectState.NOT_SUPPLIED);
|
|
|
- val.partiallySupplied += net.getAmountOfConsumerWithState(HolonObjectState.PARTIALLY_SUPPLIED);
|
|
|
- val.supplied += net.getAmountOfConsumerWithState(HolonObjectState.SUPPLIED);
|
|
|
- val.overSupplied += net.getAmountOfConsumerWithState(HolonObjectState.OVER_SUPPLIED);
|
|
|
- val.elements += net.getAmountOfElements();
|
|
|
- val.activeElements += net.getAmountOfActiveElements();
|
|
|
- val.consumption += net.getTotalConsumption();
|
|
|
- val.production += net.getTotalProduction();
|
|
|
- }
|
|
|
- val.objects = val.consumer + val.producer + val.passiv;
|
|
|
- val.difference= Math.abs(val.production - val.consumption);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- List<Flexibility> flexActiveList = control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE).stream().map(flex -> flex.getFlex()).collect(Collectors.toList());
|
|
|
- val.essentialFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Essential).count();
|
|
|
- val.highFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.High).count();
|
|
|
- val.mediumFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Medium).count();
|
|
|
- val.lowFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Low).count();
|
|
|
- val.flexebilities = val.essentialFlex + val.highFlex + val.mediumFlex + val.lowFlex;
|
|
|
- val.holon = state.getNetworkList().size();
|
|
|
- val.switches = state.getDecoratedSwitches().size();
|
|
|
- val.activeSwitches = (int)state.getDecoratedSwitches().stream().filter(dswitch -> (dswitch.getState() == SwitchState.Closed)).count();
|
|
|
-
|
|
|
- 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();
|
|
|
-
|
|
|
- val.partiallyMin = filterInf(partiallyStat.getMin());
|
|
|
- val.partiallyMax = filterInf(partiallyStat.getMax());
|
|
|
- val.partiallyAverage = filterInf(partiallyStat.getAverage());
|
|
|
-
|
|
|
- val.overMin = filterInf(overStat.getMin());
|
|
|
- val.overMax = filterInf(overStat.getMax());
|
|
|
- val.overAverage = filterInf(overStat.getAverage());
|
|
|
-
|
|
|
- return val;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private double filterInf(double value) {
|
|
|
- if(value == Double.NEGATIVE_INFINITY || value == Double.POSITIVE_INFINITY || value == Double.NaN) {
|
|
|
- return 0;
|
|
|
- }else {
|
|
|
- return value;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private String stringStatFromRunValues(RunValues val){
|
|
|
- return stringStatFromRunValues(val , "");
|
|
|
- }
|
|
|
-
|
|
|
- private String stringStatFromRunValues(RunValues val, String prefix) {
|
|
|
- return prefix +"Passiv: " + percentage(val.passiv, val.objects)
|
|
|
- + " " + prefix +"Producer: " + percentage(val.producer, val.objects)
|
|
|
- + " " + prefix +"Consumer: " + percentage(val.consumer, val.objects)
|
|
|
- + " " + prefix +"Unsupplied: " + percentage(val.unsupplied, val.objects)
|
|
|
- + " " + prefix +"Partially: " + percentage(val.partiallySupplied, val.objects)
|
|
|
- + " " + prefix +"Over: " + percentage(val.overSupplied, val.objects)
|
|
|
- + " " + prefix +"Supplied: " + percentage(val.supplied, val.objects)
|
|
|
- + " " + prefix +"Partially.SupplyPercentage.Min: " + StringFormat.doubleFixedPlaces(2, val.partiallyMin)
|
|
|
- + " " + prefix +"Partially.SupplyPercentage.Max: "+ StringFormat.doubleFixedPlaces(2, val.partiallyMax)
|
|
|
- + " " + prefix +"Partially.SupplyPercentage.Average: " + StringFormat.doubleFixedPlaces(2, val.partiallyAverage)
|
|
|
- + " " + prefix +"Over.SupplyPercentage.Min: " + StringFormat.doubleFixedPlaces(2, val.overMin)
|
|
|
- + " " + prefix +"Over.SupplyPercentage.Max: "+ StringFormat.doubleFixedPlaces(2, val.overMax)
|
|
|
- + " " + prefix +"Over.SupplyPercentage.Average: " + StringFormat.doubleFixedPlaces(2, val.overAverage)
|
|
|
- + " " + prefix +"HolonElemnts.Active:" + percentage(val.activeElements, val.elements)
|
|
|
- + " " + prefix +"Flexibilities.Essential: " + percentage(val.essentialFlex, val.flexebilities)
|
|
|
- + " " + prefix +"Flexibilities.High: " + percentage(val.highFlex, val.flexebilities)
|
|
|
- + " " + prefix +"Flexibilities.Medium: " + percentage(val.mediumFlex, val.flexebilities)
|
|
|
- + " " + prefix +"Flexibilities.Low: " + percentage(val.lowFlex, val.flexebilities)
|
|
|
- + " " + prefix +"Switches.Active:" + percentage(val.activeSwitches,val.switches)
|
|
|
- + " " + prefix +"Holons: " + val.holon
|
|
|
- + " " + prefix +"TotalConsumption: " + val.consumption
|
|
|
- + " " + prefix +"TotalProduction: " + val.production
|
|
|
- + " " + prefix +"Difference: " + val.difference;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private String percentage(double numerator , double denominator) {
|
|
|
- if((int)denominator == 0) {
|
|
|
- return "-%";
|
|
|
- }
|
|
|
- return StringFormat.doubleTwoPlaces(numerator) + "/" + StringFormat.doubleTwoPlaces(denominator) + " "+ StringFormat.doubleFixedPlaces(2,(float)numerator /(float)denominator * 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());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private class RunValues{
|
|
|
- public double result;
|
|
|
- public double executionTime;
|
|
|
-
|
|
|
- public double objects;
|
|
|
- public double passiv;
|
|
|
- public double consumer;
|
|
|
- public double supplied;
|
|
|
- public double producer;
|
|
|
- public double unsupplied;
|
|
|
- public double partiallySupplied;
|
|
|
- public double overSupplied;
|
|
|
-
|
|
|
- public double partiallyMin;
|
|
|
- public double partiallyMax;
|
|
|
- public double partiallyAverage;
|
|
|
- public double overMin;
|
|
|
- public double overMax;
|
|
|
- public double overAverage;
|
|
|
-
|
|
|
- public double activeElements;
|
|
|
- public double elements;
|
|
|
-
|
|
|
- public double essentialFlex;
|
|
|
- public double highFlex;
|
|
|
- public double mediumFlex;
|
|
|
- public double lowFlex;
|
|
|
- public double flexebilities;
|
|
|
-
|
|
|
- public double switches;
|
|
|
- public double activeSwitches;
|
|
|
-
|
|
|
- public double holon;
|
|
|
- public double consumption;
|
|
|
- public double production;
|
|
|
- public double difference;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private class RunAverage{
|
|
|
- private int runCount = 0;
|
|
|
- //Values
|
|
|
- private RunValues sum = new RunValues();
|
|
|
-
|
|
|
- public void addRun(RunValues val) {
|
|
|
- sum.result += val.result;
|
|
|
- sum.executionTime += val.executionTime;
|
|
|
- sum.passiv += val.passiv;
|
|
|
- sum.consumer += val.consumer;
|
|
|
- sum.producer += val.producer;
|
|
|
- sum.unsupplied += val.unsupplied;
|
|
|
- sum.partiallySupplied += val.partiallySupplied;
|
|
|
- sum.overSupplied += val.overSupplied;
|
|
|
- sum.activeElements += val.activeElements;
|
|
|
- sum.elements += val.elements;
|
|
|
- sum.essentialFlex += val.essentialFlex;
|
|
|
- sum.highFlex += val.highFlex;
|
|
|
- sum.mediumFlex += val.mediumFlex;
|
|
|
- sum.lowFlex += val.lowFlex;
|
|
|
- sum.flexebilities += val.flexebilities;
|
|
|
- sum.holon += val.holon;
|
|
|
- sum.switches += val.switches;
|
|
|
- sum.activeSwitches += val.activeSwitches;
|
|
|
- sum.consumption += val.consumption;
|
|
|
- sum.production += val.production;
|
|
|
- sum.difference += val.difference;
|
|
|
- sum.objects += val.objects;
|
|
|
- sum.supplied += val.supplied;
|
|
|
- sum.partiallyMin += val.partiallyMin;
|
|
|
- sum.partiallyMax += val.partiallyMax;
|
|
|
- sum.partiallyAverage += val.partiallyAverage;
|
|
|
- sum.overMin += val.overMin;
|
|
|
- sum.overMax += val.overMax;
|
|
|
- sum.overAverage += val.overAverage;
|
|
|
-
|
|
|
- runCount++;
|
|
|
- }
|
|
|
- public RunValues getAverage() {
|
|
|
- RunValues avg = new RunValues();
|
|
|
- if(runCount == 0) {
|
|
|
- return avg;
|
|
|
- }
|
|
|
- avg.result = sum.result / runCount;
|
|
|
- avg.executionTime = sum.executionTime / runCount;
|
|
|
- avg.passiv = sum.passiv / runCount;
|
|
|
- avg.consumer = sum.consumer / runCount;
|
|
|
- avg.producer = sum.producer / runCount;
|
|
|
- avg.unsupplied = sum.unsupplied / runCount;
|
|
|
- avg.partiallySupplied = sum.partiallySupplied / runCount;
|
|
|
- avg.overSupplied = sum.overSupplied / runCount;
|
|
|
- avg.activeElements = sum.activeElements / runCount;
|
|
|
- avg.elements = sum.elements / runCount;
|
|
|
- avg.essentialFlex = sum.essentialFlex / runCount;
|
|
|
- avg.highFlex = sum.highFlex / runCount;
|
|
|
- avg.mediumFlex = sum.mediumFlex / runCount;
|
|
|
- avg.lowFlex = sum.lowFlex / runCount;
|
|
|
- avg.flexebilities = sum.flexebilities / runCount;
|
|
|
- avg.holon = sum.holon / runCount;
|
|
|
- avg.switches = sum.switches / runCount;
|
|
|
- avg.activeSwitches = sum.activeSwitches / runCount;
|
|
|
- avg.consumption = sum.consumption / runCount;
|
|
|
- avg.production = sum.production / runCount;
|
|
|
- avg.difference = sum.difference / runCount;
|
|
|
- avg.objects = sum.objects / runCount;
|
|
|
- avg.supplied = sum.supplied / runCount;
|
|
|
- avg.supplied = sum.supplied / runCount;
|
|
|
- avg.partiallyMin = sum.partiallyMin / runCount;
|
|
|
- avg.partiallyMax = sum.partiallyMax / runCount;
|
|
|
- avg.partiallyAverage = sum.partiallyAverage / runCount;
|
|
|
- avg.overMin = sum.overMin / runCount;
|
|
|
- avg.overMax = sum.overMax / runCount;
|
|
|
- avg.overAverage = sum.overAverage / runCount;
|
|
|
- return avg;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private enum AccessType {None, HolonElement, Switch, Flexibility, KillSwitch};
|
|
|
- /**
|
|
|
- * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split the List.
|
|
|
- */
|
|
|
- private class AccessWrapper {
|
|
|
- private AccessType type;
|
|
|
- private List<Boolean> intialStatesOfElementForKilllSwitch;
|
|
|
-
|
|
|
- private HolonObject hObject;
|
|
|
- private HolonSwitch hSwitch;
|
|
|
-
|
|
|
- private HolonElement hElement;
|
|
|
- private Flexibility flex;
|
|
|
- private AccessWrapper correspondingKillSwitch;
|
|
|
-
|
|
|
- private boolean lastState;
|
|
|
-
|
|
|
-
|
|
|
- public AccessWrapper(HolonObject hObject){
|
|
|
- type = AccessType.KillSwitch;
|
|
|
- this.hObject = hObject;
|
|
|
- intialStatesOfElementForKilllSwitch = new ArrayList<Boolean>();
|
|
|
- for(HolonElement hE: hObject.getElements()) {
|
|
|
- intialStatesOfElementForKilllSwitch.add(hE.isActive());
|
|
|
- }
|
|
|
- }
|
|
|
- public AccessWrapper(HolonSwitch hSwitch){
|
|
|
- type = AccessType.Switch;
|
|
|
- this.hSwitch = hSwitch;
|
|
|
- }
|
|
|
- public AccessWrapper(HolonElement hElement, AccessWrapper correspondingKillSwitch){
|
|
|
- type = AccessType.HolonElement;
|
|
|
- this.hElement = hElement;
|
|
|
- this.correspondingKillSwitch = correspondingKillSwitch;
|
|
|
- }
|
|
|
-
|
|
|
- public AccessWrapper(Flexibility flex, AccessWrapper correspondingKillSwitch){
|
|
|
- type = AccessType.Flexibility;
|
|
|
- this.flex = flex;
|
|
|
- this.correspondingKillSwitch = correspondingKillSwitch;
|
|
|
- }
|
|
|
-
|
|
|
- public void setState(boolean state) {
|
|
|
- lastState = state;
|
|
|
- switch(type) {
|
|
|
- case HolonElement:
|
|
|
- if(!algoUseKillSwitch || (algoUseKillSwitch && !correspondingKillSwitch.getLastState())) {
|
|
|
- hElement.setActive(state);
|
|
|
- }
|
|
|
- break;
|
|
|
- case Switch:
|
|
|
- hSwitch.setManualMode(true);
|
|
|
- hSwitch.setManualState(state);
|
|
|
- break;
|
|
|
- case Flexibility:
|
|
|
- if(state && (!algoUseKillSwitch || (algoUseKillSwitch && !correspondingKillSwitch.getLastState()))) {
|
|
|
- control.getSimManager().getActualFlexManager().orderFlex(flex);
|
|
|
- }
|
|
|
- break;
|
|
|
- case KillSwitch:
|
|
|
- if(state) {
|
|
|
- for (HolonElement hE : hObject.getElements()) {
|
|
|
- hE.setActive(false);
|
|
|
- }
|
|
|
- }else {
|
|
|
- for(int i = 0; i < hObject.getElements().size(); i++) {
|
|
|
- hObject.getElements().get(i).setActive(intialStatesOfElementForKilllSwitch.get(i));
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public boolean getLastState() {
|
|
|
- return lastState;
|
|
|
- }
|
|
|
-
|
|
|
- public String typeString() {
|
|
|
- switch(type) {
|
|
|
- case HolonElement:
|
|
|
- return "HolonElement";
|
|
|
- case Switch:
|
|
|
- return "Switch";
|
|
|
- case Flexibility:
|
|
|
- return "Flexibility";
|
|
|
- case KillSwitch:
|
|
|
- return "KillSwitch";
|
|
|
- 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<T>{
|
|
|
- public T object;
|
|
|
- Handle(T object){
|
|
|
- this.object = object;
|
|
|
- }
|
|
|
- public String toString() {
|
|
|
- return object.toString();
|
|
|
- }
|
|
|
- }
|
|
|
- public class Individual {
|
|
|
- public double fitness;
|
|
|
- public List<Boolean> position;
|
|
|
-
|
|
|
- public Individual(){};
|
|
|
- /**
|
|
|
- * Copy Constructor
|
|
|
- */
|
|
|
- public Individual(Individual c){
|
|
|
- position = c.position.stream().collect(Collectors.toList());
|
|
|
- fitness = c.fitness;
|
|
|
- }
|
|
|
-
|
|
|
- String positionToString() {
|
|
|
- return position.stream().map(bool -> (bool?"1":"0")).collect(Collectors.joining());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected class ParameterStepping<T>{
|
|
|
- boolean useThisParameter = false;
|
|
|
- String paramaterName;
|
|
|
- private int count = 0;
|
|
|
- int stepps;
|
|
|
- T stepSize;
|
|
|
- T startValue;
|
|
|
- Consumer<T> setter;
|
|
|
- Supplier<T> getter;
|
|
|
- BiFunction<Integer,T,T> multyply;
|
|
|
- BiFunction<T,T,T> add;
|
|
|
- ParameterStepping(Consumer<T> setter, Supplier<T> getter, BiFunction<T,T,T> add, BiFunction<Integer,T,T> 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;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
+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.DoubleSummaryStatistics;
|
|
|
+import java.util.HashMap;
|
|
|
+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.JComboBox;
|
|
|
+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 addOns.Utility.EmailNotification;
|
|
|
+import algorithm.objectiveFunction.ObjectiveFunctionByCarlos;
|
|
|
+import algorithm.objectiveFunction.SwitchObjectiveFunction;
|
|
|
+import classes.AbstractCanvasObject;
|
|
|
+import classes.GroupNode;
|
|
|
+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;
|
|
|
+import utility.ImageImport;
|
|
|
+import utility.StringFormat;
|
|
|
+
|
|
|
+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<AccessWrapper> access;
|
|
|
+ private HashMap<HolonObject, AccessWrapper> accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
|
|
|
+ LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
|
|
|
+ boolean algoUseElements = false, algoUseSwitches = true, algoUseFlexes = true, algoUseKillSwitch = 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<Double> runList = new LinkedList<Double>();
|
|
|
+ private RunAverage avg = new RunAverage();
|
|
|
+
|
|
|
+ //Parameter
|
|
|
+ @SuppressWarnings("rawtypes")
|
|
|
+ LinkedList<ParameterStepping> parameterSteppingList= new LinkedList<ParameterStepping>();
|
|
|
+ protected boolean useStepping = false;
|
|
|
+
|
|
|
+ //Email
|
|
|
+ private boolean useEmailNotification = false;
|
|
|
+
|
|
|
+
|
|
|
+ //ObjectiveFunction
|
|
|
+ enum ObjectiveFunction {Normal, Switch};
|
|
|
+ ObjectiveFunction evaluationFunction = ObjectiveFunction.Normal;
|
|
|
+
|
|
|
+ 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));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+ JCheckBox useKillSwitches = new JCheckBox("KillSwitch");
|
|
|
+ useKillSwitches.setSelected(algoUseFlexes);
|
|
|
+ useKillSwitches.setBounds(900, 130, 185, 20);
|
|
|
+ useKillSwitches.addActionListener(actionEvent ->
|
|
|
+ {
|
|
|
+ cancel();
|
|
|
+ reset();
|
|
|
+ algoUseKillSwitch = useKillSwitches.isSelected();
|
|
|
+ });
|
|
|
+ parameterPanel.add(useKillSwitches);
|
|
|
+
|
|
|
+ String[] objectiveFunctionStrings = { "Normal", "Switch"};
|
|
|
+ JLabel fitnessLabel = new JLabel("FitnessFunction:");
|
|
|
+ fitnessLabel.setBounds(910, 160, 90, 20);
|
|
|
+ parameterPanel.add(fitnessLabel);
|
|
|
+ JComboBox<String> ofBox = new JComboBox<String>(objectiveFunctionStrings);
|
|
|
+ ofBox.addActionListener(actionEvent ->
|
|
|
+ {
|
|
|
+ boolean pickNormal = ((String)ofBox.getSelectedItem()).equals("Normal");
|
|
|
+ evaluationFunction = pickNormal?ObjectiveFunction.Normal:ObjectiveFunction.Switch;
|
|
|
+ });
|
|
|
+ ofBox.setBounds(1000, 160, 70, 20);
|
|
|
+ parameterPanel.add(ofBox);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ JCheckBox emailNotificationCheckbox = new JCheckBox("EmailNotification");
|
|
|
+ emailNotificationCheckbox.setSelected(this.useEmailNotification);
|
|
|
+ emailNotificationCheckbox.setBounds(900, 200, 130, 20);
|
|
|
+ emailNotificationCheckbox.addActionListener(actionEvent -> useEmailNotification = emailNotificationCheckbox.isSelected());
|
|
|
+ parameterPanel.add(emailNotificationCheckbox);
|
|
|
+
|
|
|
+ JButton emailSettingsButton = new JButton("", new ImageIcon(ImageImport.loadImage("/Images/settingsIcon.png", 16,16)));
|
|
|
+ emailSettingsButton.setBounds(1030, 200, 20, 20);
|
|
|
+ emailSettingsButton.addActionListener(event -> {
|
|
|
+ EmailNotification.OpenEmailSettings(content);
|
|
|
+ });
|
|
|
+ parameterPanel.add(emailSettingsButton);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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<Integer> setter, Supplier<Integer> getter) {
|
|
|
+ this.addIntParameter(parameterName, parameterValue, setter, getter, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void addIntParameter(String parameterName, int parameterValue, Consumer<Integer> setter, Supplier<Integer> getter, int parameterMinValue) {
|
|
|
+ this.addIntParameter(parameterName, parameterValue, setter, getter, parameterMinValue, Integer.MAX_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void addIntParameter(String parameterName, int parameterValue, Consumer<Integer> setter, Supplier<Integer> 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<Integer> intParameterStepping = new ParameterStepping<Integer>(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<Double> setter, Supplier<Double> getter) {
|
|
|
+ this.addDoubleParameter(parameterName, parameterValue, setter, getter, Double.MIN_VALUE, Double.MAX_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected void addDoubleParameter(String parameterName, double parameterValue, Consumer<Double> setter, Supplier<Double> getter, double parameterMinValue) {
|
|
|
+ this.addDoubleParameter(parameterName, parameterValue, setter, getter, parameterMinValue, Double.MAX_VALUE);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected void addDoubleParameter(String parameterName, double parameterValue, Consumer<Double> setter, Supplier<Double> 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<Double> doubleParameterStepping = new ParameterStepping<Double>(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<Boolean> 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<DecoratedGroupNode>(aCps)).toArray();
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Handle<DecoratedGroupNode> selected = (Handle<DecoratedGroupNode>) 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<Boolean> positionToEvaluate) {
|
|
|
+ runProgressbar.step();
|
|
|
+ setState(positionToEvaluate); // execution time critical
|
|
|
+ DecoratedState actualstate = control.getSimManager().getActualDecorState();
|
|
|
+ double result = evaluateState(actualstate);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private double evaluateState(DecoratedState actualstate) {
|
|
|
+ switch(this.evaluationFunction) {
|
|
|
+ case Switch:
|
|
|
+ return SwitchObjectiveFunction.getFitnessValueForState(actualstate);
|
|
|
+ case Normal:
|
|
|
+ default:
|
|
|
+ return ObjectiveFunctionByCarlos.getFitnessValueForState(actualstate);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void run() {
|
|
|
+ cancel = false;
|
|
|
+ control.guiDisable(true);
|
|
|
+ runPrinter.openStream();
|
|
|
+ runPrinter.println("");
|
|
|
+ runPrinter.println("Start:" + stringStatFromRunValues(getRunValuesFromActualState()));
|
|
|
+ runPrinter.closeStream();
|
|
|
+ if(this.useStepping) {
|
|
|
+ initParameterStepping();
|
|
|
+ do {
|
|
|
+ executeAlgoWithParameter();
|
|
|
+ if(cancel) break;
|
|
|
+ resetState();
|
|
|
+ }while(updateOneParameter());
|
|
|
+ resetParameterStepping();
|
|
|
+ }else {
|
|
|
+ executeAlgoWithParameter();
|
|
|
+
|
|
|
+ }
|
|
|
+ updateVisual();
|
|
|
+ runProgressbar.finishedCancel();
|
|
|
+ control.guiDisable(false);
|
|
|
+ if(this.useEmailNotification && !cancel) {
|
|
|
+ EmailNotification.sendEmail(this.getClass().getName() + " finished", "Execution done.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ @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<ParameterStepping> 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(algoInformationToPrint());
|
|
|
+ console.println(algoInformationToPrint());
|
|
|
+ runPrinter.closeStream();
|
|
|
+ runProgressbar.start();
|
|
|
+ Individual runBest = new Individual();
|
|
|
+ runBest.fitness = Double.MAX_VALUE;
|
|
|
+ this.avg = new RunAverage();
|
|
|
+ for(int r = 0; r < rounds; r++)
|
|
|
+ {
|
|
|
+ startTimer();
|
|
|
+ Individual roundBest = executeAlgo();
|
|
|
+ if(cancel)return;
|
|
|
+ long executionTime = printElapsedTime();
|
|
|
+ setState(roundBest.position);
|
|
|
+ runPrinter.openStream();
|
|
|
+ runPrinter.println(runList.stream().map(value -> StringFormat.doubleFixedPlaces(2,value)).collect(Collectors.joining(", ")));
|
|
|
+ RunValues val = getRunValuesFromActualState();
|
|
|
+ val.result = roundBest.fitness;
|
|
|
+ val.executionTime = executionTime;
|
|
|
+ avg.addRun(val);
|
|
|
+ runPrinter.println("Result: " + StringFormat.doubleFixedPlaces(2,roundBest.fitness) + " ExecutionTime:" + executionTime + " " + stringStatFromRunValues(val));
|
|
|
+ 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: " + StringFormat.doubleFixedPlaces(2,startFitness));
|
|
|
+ console.println("AlgoResult: " + StringFormat.doubleFixedPlaces(2,runBest.fitness));
|
|
|
+ if(this.algoUseFlexes)calculateAndPrintFlexInfos(control.getSimManager().getActualDecorState());
|
|
|
+ runPrinter.openStream();
|
|
|
+ if(rounds > 1) {
|
|
|
+ RunValues avgRun = avg.getAverage();
|
|
|
+
|
|
|
+ runPrinter.println("Average.Result: " + StringFormat.doubleFixedPlaces(2, avgRun.result) + " Average.ExecutionTime:" + avgRun.executionTime + " " + this.stringStatFromRunValues(avg.getAverage(), "Average."));
|
|
|
+ }
|
|
|
+ runPrinter.println("");
|
|
|
+ runPrinter.closeStream();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ 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());
|
|
|
+ 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() {
|
|
|
+ setState(resetChain.getLast());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Sets the State out of the given position for calculation or to show the user.
|
|
|
+ * @param position
|
|
|
+ */
|
|
|
+ private void setState(List<Boolean> position) {
|
|
|
+ control.getSimManager().resetFlexManagerForTimeStep(control.getModel().getCurIteration());
|
|
|
+ int i = 0;
|
|
|
+ for(Boolean bool: position) {
|
|
|
+ access.get(i++).setState(bool);
|
|
|
+ }
|
|
|
+ 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<Boolean> extractPositionAndAccess() {
|
|
|
+ Model model = control.getModel();
|
|
|
+ this.accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
|
|
|
+ access= new ArrayList<AccessWrapper>();
|
|
|
+ List<Boolean> initialState = new ArrayList<Boolean>();
|
|
|
+ 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)){
|
|
|
+ //flex.getFlex().getElement().parentObject;
|
|
|
+ AccessWrapper killSwitchAccess = this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getFlex().getElement().parentObject): null;;
|
|
|
+ access.add(new AccessWrapper(flex.getFlex(), killSwitchAccess));
|
|
|
+ initialState.add(false);
|
|
|
+ }
|
|
|
+ for(FlexWrapper flex :control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE)){
|
|
|
+ AccessWrapper killSwitchAccess = this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getFlex().getElement().parentObject): null;
|
|
|
+ access.add(new AccessWrapper(flex.getFlex(), killSwitchAccess));
|
|
|
+ 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<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
|
|
|
+ for(AbstractCanvasObject aCps : nodes) {
|
|
|
+ if (aCps instanceof HolonObject) {
|
|
|
+ HolonObject hObject = (HolonObject) aCps;
|
|
|
+ AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
|
|
|
+ if(this.algoUseKillSwitch) {
|
|
|
+ positionToInit.add(false);
|
|
|
+ access.add(killSwitchAccess);
|
|
|
+ accessKillSwitch.put(hObject, killSwitchAccess);
|
|
|
+ }
|
|
|
+ if(this.algoUseElements) {
|
|
|
+ for (HolonElement hE : hObject.getElements()) {
|
|
|
+ positionToInit.add(hE.isActive());
|
|
|
+ access.add(new AccessWrapper(hE, killSwitchAccess));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (aCps instanceof HolonSwitch&& algoUseSwitches) {
|
|
|
+ HolonSwitch sw = (HolonSwitch) aCps;
|
|
|
+ positionToInit.add(sw.getState(timeStep));
|
|
|
+ access.add(new AccessWrapper(sw));
|
|
|
+ }
|
|
|
+ else if(aCps instanceof GroupNode) {
|
|
|
+ rollOutNodes(((GroupNode)aCps).getNodes(), positionToInit ,timeStep );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private RunValues getRunValuesFromActualState() {
|
|
|
+ RunValues val = new RunValues();
|
|
|
+ if(dGroupNode != null)
|
|
|
+ {
|
|
|
+ //GetActualDecoratedGroupNode
|
|
|
+ dGroupNode = control.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().get(dGroupNode.getModel());
|
|
|
+ val.producer = dGroupNode.getAmountOfSupplier();
|
|
|
+ val.consumer = dGroupNode.getAmountOfConsumer();
|
|
|
+ val.passiv = dGroupNode.getAmountOfPassiv();
|
|
|
+ val.objects = val.producer + val.consumer + val.passiv;
|
|
|
+ val.unsupplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.NOT_SUPPLIED);
|
|
|
+ val.partiallySupplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.PARTIALLY_SUPPLIED);
|
|
|
+ val.supplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.SUPPLIED);
|
|
|
+ val.overSupplied = dGroupNode.getAmountOfConsumerWithState(HolonObjectState.OVER_SUPPLIED);
|
|
|
+
|
|
|
+
|
|
|
+ val.activeElements = dGroupNode.getAmountOfAktiveElemntsFromHolonObjects();
|
|
|
+ val.elements = dGroupNode.getAmountOfElemntsFromHolonObjects();
|
|
|
+ //TODO what should be printed happen when only groupNode are selected
|
|
|
+ }
|
|
|
+ DecoratedState state = control.getSimManager().getActualDecorState();
|
|
|
+ for(DecoratedNetwork net : state.getNetworkList()) {
|
|
|
+ val.consumer += net.getAmountOfConsumer();
|
|
|
+ val.producer += net.getAmountOfSupplier();
|
|
|
+ val.passiv += net.getAmountOfPassiv();
|
|
|
+ val.unsupplied += net.getAmountOfConsumerWithState(HolonObjectState.NOT_SUPPLIED);
|
|
|
+ val.partiallySupplied += net.getAmountOfConsumerWithState(HolonObjectState.PARTIALLY_SUPPLIED);
|
|
|
+ val.supplied += net.getAmountOfConsumerWithState(HolonObjectState.SUPPLIED);
|
|
|
+ val.overSupplied += net.getAmountOfConsumerWithState(HolonObjectState.OVER_SUPPLIED);
|
|
|
+ val.elements += net.getAmountOfElements();
|
|
|
+ val.activeElements += net.getAmountOfActiveElements();
|
|
|
+ val.consumption += net.getTotalConsumption();
|
|
|
+ val.production += net.getTotalProduction();
|
|
|
+ }
|
|
|
+ val.objects = val.consumer + val.producer + val.passiv;
|
|
|
+ val.difference= Math.abs(val.production - val.consumption);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ List<Flexibility> flexActiveList = control.getSimManager().getActualFlexManager().getAllFlexWrapperWithState(FlexState.IN_USE).stream().map(flex -> flex.getFlex()).collect(Collectors.toList());
|
|
|
+ val.essentialFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Essential).count();
|
|
|
+ val.highFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.High).count();
|
|
|
+ val.mediumFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Medium).count();
|
|
|
+ val.lowFlex = (int)flexActiveList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Low).count();
|
|
|
+ val.flexebilities = val.essentialFlex + val.highFlex + val.mediumFlex + val.lowFlex;
|
|
|
+ val.holon = state.getNetworkList().size();
|
|
|
+ val.switches = state.getDecoratedSwitches().size();
|
|
|
+ val.activeSwitches = (int)state.getDecoratedSwitches().stream().filter(dswitch -> (dswitch.getState() == SwitchState.Closed)).count();
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+ val.partiallyMin = filterInf(partiallyStat.getMin());
|
|
|
+ val.partiallyMax = filterInf(partiallyStat.getMax());
|
|
|
+ val.partiallyAverage = filterInf(partiallyStat.getAverage());
|
|
|
+
|
|
|
+ val.overMin = filterInf(overStat.getMin());
|
|
|
+ val.overMax = filterInf(overStat.getMax());
|
|
|
+ val.overAverage = filterInf(overStat.getAverage());
|
|
|
+
|
|
|
+ return val;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private double filterInf(double value) {
|
|
|
+ if(value == Double.NEGATIVE_INFINITY || value == Double.POSITIVE_INFINITY || value == Double.NaN) {
|
|
|
+ return 0;
|
|
|
+ }else {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String stringStatFromRunValues(RunValues val){
|
|
|
+ return stringStatFromRunValues(val , "");
|
|
|
+ }
|
|
|
+
|
|
|
+ private String stringStatFromRunValues(RunValues val, String prefix) {
|
|
|
+ return prefix +"Passiv: " + percentage(val.passiv, val.objects)
|
|
|
+ + " " + prefix +"Producer: " + percentage(val.producer, val.objects)
|
|
|
+ + " " + prefix +"Consumer: " + percentage(val.consumer, val.objects)
|
|
|
+ + " " + prefix +"Unsupplied: " + percentage(val.unsupplied, val.objects)
|
|
|
+ + " " + prefix +"Partially: " + percentage(val.partiallySupplied, val.objects)
|
|
|
+ + " " + prefix +"Over: " + percentage(val.overSupplied, val.objects)
|
|
|
+ + " " + prefix +"Supplied: " + percentage(val.supplied, val.objects)
|
|
|
+ + " " + prefix +"Partially.SupplyPercentage.Min: " + StringFormat.doubleFixedPlaces(2, val.partiallyMin)
|
|
|
+ + " " + prefix +"Partially.SupplyPercentage.Max: "+ StringFormat.doubleFixedPlaces(2, val.partiallyMax)
|
|
|
+ + " " + prefix +"Partially.SupplyPercentage.Average: " + StringFormat.doubleFixedPlaces(2, val.partiallyAverage)
|
|
|
+ + " " + prefix +"Over.SupplyPercentage.Min: " + StringFormat.doubleFixedPlaces(2, val.overMin)
|
|
|
+ + " " + prefix +"Over.SupplyPercentage.Max: "+ StringFormat.doubleFixedPlaces(2, val.overMax)
|
|
|
+ + " " + prefix +"Over.SupplyPercentage.Average: " + StringFormat.doubleFixedPlaces(2, val.overAverage)
|
|
|
+ + " " + prefix +"HolonElemnts.Active:" + percentage(val.activeElements, val.elements)
|
|
|
+ + " " + prefix +"Flexibilities.Essential: " + percentage(val.essentialFlex, val.flexebilities)
|
|
|
+ + " " + prefix +"Flexibilities.High: " + percentage(val.highFlex, val.flexebilities)
|
|
|
+ + " " + prefix +"Flexibilities.Medium: " + percentage(val.mediumFlex, val.flexebilities)
|
|
|
+ + " " + prefix +"Flexibilities.Low: " + percentage(val.lowFlex, val.flexebilities)
|
|
|
+ + " " + prefix +"Switches.Active:" + percentage(val.activeSwitches,val.switches)
|
|
|
+ + " " + prefix +"Holons: " + val.holon
|
|
|
+ + " " + prefix +"TotalConsumption: " + val.consumption
|
|
|
+ + " " + prefix +"TotalProduction: " + val.production
|
|
|
+ + " " + prefix +"Difference: " + val.difference;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private String percentage(double numerator , double denominator) {
|
|
|
+ if((int)denominator == 0) {
|
|
|
+ return "-%";
|
|
|
+ }
|
|
|
+ return StringFormat.doubleTwoPlaces(numerator) + "/" + StringFormat.doubleTwoPlaces(denominator) + " "+ StringFormat.doubleFixedPlaces(2,(float)numerator /(float)denominator * 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());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private class RunValues{
|
|
|
+ public double result;
|
|
|
+ public double executionTime;
|
|
|
+
|
|
|
+ public double objects;
|
|
|
+ public double passiv;
|
|
|
+ public double consumer;
|
|
|
+ public double supplied;
|
|
|
+ public double producer;
|
|
|
+ public double unsupplied;
|
|
|
+ public double partiallySupplied;
|
|
|
+ public double overSupplied;
|
|
|
+
|
|
|
+ public double partiallyMin;
|
|
|
+ public double partiallyMax;
|
|
|
+ public double partiallyAverage;
|
|
|
+ public double overMin;
|
|
|
+ public double overMax;
|
|
|
+ public double overAverage;
|
|
|
+
|
|
|
+ public double activeElements;
|
|
|
+ public double elements;
|
|
|
+
|
|
|
+ public double essentialFlex;
|
|
|
+ public double highFlex;
|
|
|
+ public double mediumFlex;
|
|
|
+ public double lowFlex;
|
|
|
+ public double flexebilities;
|
|
|
+
|
|
|
+ public double switches;
|
|
|
+ public double activeSwitches;
|
|
|
+
|
|
|
+ public double holon;
|
|
|
+ public double consumption;
|
|
|
+ public double production;
|
|
|
+ public double difference;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private class RunAverage{
|
|
|
+ private int runCount = 0;
|
|
|
+ //Values
|
|
|
+ private RunValues sum = new RunValues();
|
|
|
+
|
|
|
+ public void addRun(RunValues val) {
|
|
|
+ sum.result += val.result;
|
|
|
+ sum.executionTime += val.executionTime;
|
|
|
+ sum.passiv += val.passiv;
|
|
|
+ sum.consumer += val.consumer;
|
|
|
+ sum.producer += val.producer;
|
|
|
+ sum.unsupplied += val.unsupplied;
|
|
|
+ sum.partiallySupplied += val.partiallySupplied;
|
|
|
+ sum.overSupplied += val.overSupplied;
|
|
|
+ sum.activeElements += val.activeElements;
|
|
|
+ sum.elements += val.elements;
|
|
|
+ sum.essentialFlex += val.essentialFlex;
|
|
|
+ sum.highFlex += val.highFlex;
|
|
|
+ sum.mediumFlex += val.mediumFlex;
|
|
|
+ sum.lowFlex += val.lowFlex;
|
|
|
+ sum.flexebilities += val.flexebilities;
|
|
|
+ sum.holon += val.holon;
|
|
|
+ sum.switches += val.switches;
|
|
|
+ sum.activeSwitches += val.activeSwitches;
|
|
|
+ sum.consumption += val.consumption;
|
|
|
+ sum.production += val.production;
|
|
|
+ sum.difference += val.difference;
|
|
|
+ sum.objects += val.objects;
|
|
|
+ sum.supplied += val.supplied;
|
|
|
+ sum.partiallyMin += val.partiallyMin;
|
|
|
+ sum.partiallyMax += val.partiallyMax;
|
|
|
+ sum.partiallyAverage += val.partiallyAverage;
|
|
|
+ sum.overMin += val.overMin;
|
|
|
+ sum.overMax += val.overMax;
|
|
|
+ sum.overAverage += val.overAverage;
|
|
|
+
|
|
|
+ runCount++;
|
|
|
+ }
|
|
|
+ public RunValues getAverage() {
|
|
|
+ RunValues avg = new RunValues();
|
|
|
+ if(runCount == 0) {
|
|
|
+ return avg;
|
|
|
+ }
|
|
|
+ avg.result = sum.result / runCount;
|
|
|
+ avg.executionTime = sum.executionTime / runCount;
|
|
|
+ avg.passiv = sum.passiv / runCount;
|
|
|
+ avg.consumer = sum.consumer / runCount;
|
|
|
+ avg.producer = sum.producer / runCount;
|
|
|
+ avg.unsupplied = sum.unsupplied / runCount;
|
|
|
+ avg.partiallySupplied = sum.partiallySupplied / runCount;
|
|
|
+ avg.overSupplied = sum.overSupplied / runCount;
|
|
|
+ avg.activeElements = sum.activeElements / runCount;
|
|
|
+ avg.elements = sum.elements / runCount;
|
|
|
+ avg.essentialFlex = sum.essentialFlex / runCount;
|
|
|
+ avg.highFlex = sum.highFlex / runCount;
|
|
|
+ avg.mediumFlex = sum.mediumFlex / runCount;
|
|
|
+ avg.lowFlex = sum.lowFlex / runCount;
|
|
|
+ avg.flexebilities = sum.flexebilities / runCount;
|
|
|
+ avg.holon = sum.holon / runCount;
|
|
|
+ avg.switches = sum.switches / runCount;
|
|
|
+ avg.activeSwitches = sum.activeSwitches / runCount;
|
|
|
+ avg.consumption = sum.consumption / runCount;
|
|
|
+ avg.production = sum.production / runCount;
|
|
|
+ avg.difference = sum.difference / runCount;
|
|
|
+ avg.objects = sum.objects / runCount;
|
|
|
+ avg.supplied = sum.supplied / runCount;
|
|
|
+ avg.supplied = sum.supplied / runCount;
|
|
|
+ avg.partiallyMin = sum.partiallyMin / runCount;
|
|
|
+ avg.partiallyMax = sum.partiallyMax / runCount;
|
|
|
+ avg.partiallyAverage = sum.partiallyAverage / runCount;
|
|
|
+ avg.overMin = sum.overMin / runCount;
|
|
|
+ avg.overMax = sum.overMax / runCount;
|
|
|
+ avg.overAverage = sum.overAverage / runCount;
|
|
|
+ return avg;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private enum AccessType {None, HolonElement, Switch, Flexibility, KillSwitch};
|
|
|
+ /**
|
|
|
+ * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split the List.
|
|
|
+ */
|
|
|
+ private class AccessWrapper {
|
|
|
+ private AccessType type;
|
|
|
+ private List<Boolean> intialStatesOfElementForKilllSwitch;
|
|
|
+
|
|
|
+ private HolonObject hObject;
|
|
|
+ private HolonSwitch hSwitch;
|
|
|
+
|
|
|
+ private HolonElement hElement;
|
|
|
+ private Flexibility flex;
|
|
|
+ private AccessWrapper correspondingKillSwitch;
|
|
|
+
|
|
|
+ private boolean lastState;
|
|
|
+
|
|
|
+
|
|
|
+ public AccessWrapper(HolonObject hObject){
|
|
|
+ type = AccessType.KillSwitch;
|
|
|
+ this.hObject = hObject;
|
|
|
+ intialStatesOfElementForKilllSwitch = new ArrayList<Boolean>();
|
|
|
+ for(HolonElement hE: hObject.getElements()) {
|
|
|
+ intialStatesOfElementForKilllSwitch.add(hE.isActive());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public AccessWrapper(HolonSwitch hSwitch){
|
|
|
+ type = AccessType.Switch;
|
|
|
+ this.hSwitch = hSwitch;
|
|
|
+ }
|
|
|
+ public AccessWrapper(HolonElement hElement, AccessWrapper correspondingKillSwitch){
|
|
|
+ type = AccessType.HolonElement;
|
|
|
+ this.hElement = hElement;
|
|
|
+ this.correspondingKillSwitch = correspondingKillSwitch;
|
|
|
+ }
|
|
|
+
|
|
|
+ public AccessWrapper(Flexibility flex, AccessWrapper correspondingKillSwitch){
|
|
|
+ type = AccessType.Flexibility;
|
|
|
+ this.flex = flex;
|
|
|
+ this.correspondingKillSwitch = correspondingKillSwitch;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setState(boolean state) {
|
|
|
+ lastState = state;
|
|
|
+ switch(type) {
|
|
|
+ case HolonElement:
|
|
|
+ if(!algoUseKillSwitch || (algoUseKillSwitch && !correspondingKillSwitch.getLastState())) {
|
|
|
+ hElement.setActive(state);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case Switch:
|
|
|
+ hSwitch.setManualMode(true);
|
|
|
+ hSwitch.setManualState(state);
|
|
|
+ break;
|
|
|
+ case Flexibility:
|
|
|
+ if(state && (!algoUseKillSwitch || (algoUseKillSwitch && !correspondingKillSwitch.getLastState()))) {
|
|
|
+ control.getSimManager().getActualFlexManager().orderFlex(flex);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case KillSwitch:
|
|
|
+ if(state) {
|
|
|
+ for (HolonElement hE : hObject.getElements()) {
|
|
|
+ hE.setActive(false);
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ for(int i = 0; i < hObject.getElements().size(); i++) {
|
|
|
+ hObject.getElements().get(i).setActive(intialStatesOfElementForKilllSwitch.get(i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean getLastState() {
|
|
|
+ return lastState;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String typeString() {
|
|
|
+ switch(type) {
|
|
|
+ case HolonElement:
|
|
|
+ return "HolonElement";
|
|
|
+ case Switch:
|
|
|
+ return "Switch";
|
|
|
+ case Flexibility:
|
|
|
+ return "Flexibility";
|
|
|
+ case KillSwitch:
|
|
|
+ return "KillSwitch";
|
|
|
+ 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<T>{
|
|
|
+ public T object;
|
|
|
+ Handle(T object){
|
|
|
+ this.object = object;
|
|
|
+ }
|
|
|
+ public String toString() {
|
|
|
+ return object.toString();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public class Individual {
|
|
|
+ public double fitness;
|
|
|
+ public List<Boolean> position;
|
|
|
+
|
|
|
+ public Individual(){};
|
|
|
+ /**
|
|
|
+ * Copy Constructor
|
|
|
+ */
|
|
|
+ public Individual(Individual c){
|
|
|
+ position = c.position.stream().collect(Collectors.toList());
|
|
|
+ fitness = c.fitness;
|
|
|
+ }
|
|
|
+
|
|
|
+ String positionToString() {
|
|
|
+ return position.stream().map(bool -> (bool?"1":"0")).collect(Collectors.joining());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected class ParameterStepping<T>{
|
|
|
+ boolean useThisParameter = false;
|
|
|
+ String paramaterName;
|
|
|
+ private int count = 0;
|
|
|
+ int stepps;
|
|
|
+ T stepSize;
|
|
|
+ T startValue;
|
|
|
+ Consumer<T> setter;
|
|
|
+ Supplier<T> getter;
|
|
|
+ BiFunction<Integer,T,T> multyply;
|
|
|
+ BiFunction<T,T,T> add;
|
|
|
+ ParameterStepping(Consumer<T> setter, Supplier<T> getter, BiFunction<T,T,T> add, BiFunction<Integer,T,T> 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|