|
@@ -1,5 +1,22 @@
|
|
|
package holeg.api;
|
|
|
|
|
|
+import holeg.addon.helper.EmailNotification;
|
|
|
+import holeg.algorithm.objective_function.ObjectiveFunctionByCarlos;
|
|
|
+import holeg.algorithm.objective_function.SwitchObjectiveFunction;
|
|
|
+import holeg.model.Flexibility;
|
|
|
+import holeg.model.Flexibility.FlexState;
|
|
|
+import holeg.model.GroupNode;
|
|
|
+import holeg.model.HolonElement;
|
|
|
+import holeg.model.HolonObject;
|
|
|
+import holeg.model.HolonSwitch;
|
|
|
+import holeg.model.HolonSwitch.SwitchMode;
|
|
|
+import holeg.model.HolonSwitch.SwitchState;
|
|
|
+import holeg.model.Model;
|
|
|
+import holeg.preferences.ImagePreference;
|
|
|
+import holeg.ui.controller.Control;
|
|
|
+import holeg.ui.view.component.Console;
|
|
|
+import holeg.ui.view.image.Import;
|
|
|
+import holeg.utility.math.decimal.Format;
|
|
|
import java.awt.BorderLayout;
|
|
|
import java.awt.Component;
|
|
|
import java.awt.Dimension;
|
|
@@ -12,13 +29,21 @@ import java.io.IOException;
|
|
|
import java.io.OutputStreamWriter;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.text.NumberFormat;
|
|
|
-import java.util.*;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.DoubleSummaryStatistics;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Locale;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Optional;
|
|
|
import java.util.function.BiFunction;
|
|
|
import java.util.function.Consumer;
|
|
|
import java.util.function.Supplier;
|
|
|
import java.util.stream.Collectors;
|
|
|
import java.util.stream.Stream;
|
|
|
-
|
|
|
import javax.swing.BorderFactory;
|
|
|
import javax.swing.Box;
|
|
|
import javax.swing.BoxLayout;
|
|
@@ -36,1302 +61,1326 @@ import javax.swing.JScrollPane;
|
|
|
import javax.swing.JSplitPane;
|
|
|
import javax.swing.text.NumberFormatter;
|
|
|
|
|
|
-import holeg.addon.helper.EmailNotification;
|
|
|
-import holeg.algorithm.objective_function.ObjectiveFunctionByCarlos;
|
|
|
-import holeg.algorithm.objective_function.SwitchObjectiveFunction;
|
|
|
-import holeg.model.*;
|
|
|
-import holeg.preferences.ImagePreference;
|
|
|
-import holeg.model.Flexibility.FlexState;
|
|
|
-import holeg.model.HolonSwitch.SwitchMode;
|
|
|
-import holeg.model.HolonSwitch.SwitchState;
|
|
|
-import holeg.ui.controller.Control;
|
|
|
-import holeg.ui.view.component.Console;
|
|
|
-import holeg.ui.view.image.Import;
|
|
|
-import holeg.utility.math.decimal.Format;
|
|
|
+public abstract class AlgorithmFrameworkFlex implements AddOn {
|
|
|
|
|
|
-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 Optional<GroupNode> groupNode = Optional.empty();
|
|
|
-
|
|
|
-
|
|
|
- //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 useSmartMeter = new JCheckBox("SmartMeter");
|
|
|
- useSmartMeter.setSelected(algoUseFlexes);
|
|
|
- useSmartMeter.setBounds(900, 130, 185, 20);
|
|
|
- useSmartMeter.addActionListener(actionEvent ->
|
|
|
- {
|
|
|
- cancel();
|
|
|
- reset();
|
|
|
- algoUseKillSwitch = useSmartMeter.isSelected();
|
|
|
- });
|
|
|
- parameterPanel.add(useSmartMeter);
|
|
|
-
|
|
|
- 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(Import.loadImage(ImagePreference.Button.Settings, 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 the initial grid configuration.");
|
|
|
- resetButton.addActionListener(actionEvent -> reset());
|
|
|
- buttonPanel.add(resetButton);
|
|
|
-
|
|
|
- JButton cancelButton = new JButton("Cancel Run");
|
|
|
- cancelButton.addActionListener(actionEvent -> cancel());
|
|
|
- buttonPanel.add(cancelButton);
|
|
|
-
|
|
|
- JButton fitnessButton = new JButton("Evaluate");
|
|
|
- fitnessButton.setToolTipText("Evaluate the current grid configuration.");
|
|
|
- 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("Step size: ");
|
|
|
- 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("Step size: ");
|
|
|
- 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 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.getModel().getCanvas().getAllGroupNodeObjectsRecursive().toArray();
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- GroupNode selected = (GroupNode) 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);
|
|
|
- groupNode = Optional.of(selected);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected double evaluatePosition(List<Boolean> positionToEvaluate) {
|
|
|
- runProgressbar.step();
|
|
|
- setState(positionToEvaluate); // execution time critical
|
|
|
- double result = evaluateState();
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- private double evaluateState() {
|
|
|
- switch(this.evaluationFunction) {
|
|
|
- case Switch:
|
|
|
- return SwitchObjectiveFunction.getFitnessValueForState(control.getModel());
|
|
|
- case Normal:
|
|
|
- default:
|
|
|
- return ObjectiveFunctionByCarlos.getFitnessValueForState(control.getModel());
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private void run() {
|
|
|
- cancel = false;
|
|
|
- control.guiSetEnabled(false);
|
|
|
- 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.guiSetEnabled(true);
|
|
|
- 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 -> Format.doubleFixedPlaces(2,value)).collect(Collectors.joining(", ")));
|
|
|
- RunValues val = getRunValuesFromActualState();
|
|
|
- val.result = roundBest.fitness;
|
|
|
- val.executionTime = executionTime;
|
|
|
- avg.addRun(val);
|
|
|
- runPrinter.println("Result: " + Format.doubleFixedPlaces(2,roundBest.fitness) + " ExecutionTime:" + executionTime + " " + stringStatFromRunValues(val));
|
|
|
- runPrinter.closeStream();
|
|
|
- resetState();
|
|
|
- if(roundBest.fitness < runBest.fitness) runBest = roundBest;
|
|
|
- }
|
|
|
-
|
|
|
- this.extractPositionAndAccess();
|
|
|
- setState(runBest.position);
|
|
|
- updateVisual();
|
|
|
- console.println("Start: " + Format.doubleFixedPlaces(2,startFitness));
|
|
|
- console.println("AlgoResult: " + Format.doubleFixedPlaces(2,runBest.fitness));
|
|
|
- if(this.algoUseFlexes)calculateAndPrintFlexInfos();
|
|
|
- runPrinter.openStream();
|
|
|
- if(rounds > 1) {
|
|
|
- RunValues avgRun = avg.getAverage();
|
|
|
-
|
|
|
- runPrinter.println("Average.Result: " + Format.doubleFixedPlaces(2, avgRun.result) + " Average.ExecutionTime:" + avgRun.executionTime + " " + avg.getAverage().stringStatFromRunValues("Average."));
|
|
|
- }
|
|
|
- runPrinter.println("");
|
|
|
- runPrinter.closeStream();
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private void calculateAndPrintFlexInfos() {
|
|
|
- int amountOfUsedFlex = 0;
|
|
|
- List<Flexibility> allFlex = control.getModel().getAllFlexibilities();
|
|
|
- int amountOfFlex = allFlex.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;
|
|
|
- Stream<Flexibility> allFlexInUse = allFlex.stream().filter(flex -> flex.getState().equals(FlexState.IN_USE));
|
|
|
- Iterator<Flexibility> iterInUseFlex = allFlexInUse.iterator();
|
|
|
- while(iterInUseFlex.hasNext()) {
|
|
|
- Flexibility flex = iterInUseFlex.next();
|
|
|
- amountOfUsedFlex++;
|
|
|
- cost += flex.cost;
|
|
|
- float energy = flex.energyReleased();
|
|
|
- if(energy < 0) {
|
|
|
- consumingFlex++;
|
|
|
- consumingFlexEnergy += -energy;
|
|
|
- }else {
|
|
|
- producingFlex++;
|
|
|
- producingFlexEnergy += energy;
|
|
|
- }
|
|
|
- if(flex.getCooldown() > maxCooldown) maxCooldown = flex.getCooldown();
|
|
|
- switch(flex.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);
|
|
|
- //
|
|
|
-
|
|
|
- }
|
|
|
+ //Algo
|
|
|
+ protected int rounds = 1;
|
|
|
+ protected Console console = new Console();
|
|
|
+ protected boolean cancel = false;
|
|
|
+ //holeg interaction
|
|
|
+ protected Control control;
|
|
|
+ protected List<Double> runList = new LinkedList<Double>();
|
|
|
+ protected boolean useStepping = false;
|
|
|
+ LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
|
|
|
+ boolean algoUseElements = false, algoUseSwitches = true, algoUseFlexes = true, algoUseKillSwitch = true;
|
|
|
+ //Parameter
|
|
|
+ @SuppressWarnings("rawtypes")
|
|
|
+ LinkedList<ParameterStepping> parameterSteppingList = new LinkedList<ParameterStepping>();
|
|
|
+ ObjectiveFunction evaluationFunction = ObjectiveFunction.Normal;
|
|
|
+ //Panel
|
|
|
+ private JPanel content = new JPanel();
|
|
|
+ private JPanel borderPanel = new JPanel();
|
|
|
+ //Settings groupNode
|
|
|
+ private Optional<GroupNode> groupNode = Optional.empty();
|
|
|
+ //access
|
|
|
+ private ArrayList<AccessWrapper> access;
|
|
|
+ private HashMap<HolonObject, AccessWrapper> accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
|
|
|
+ //time
|
|
|
+ private long startTime;
|
|
|
+ private RunProgressBar runProgressbar = new RunProgressBar();
|
|
|
+ //concurrency
|
|
|
+ private Thread runThread = new Thread();
|
|
|
+ //printing
|
|
|
+ private Printer runPrinter = new Printer(plottFileName());
|
|
|
+ private RunAverage avg = new RunAverage();
|
|
|
+ //Email
|
|
|
+ private boolean useEmailNotification = false;
|
|
|
|
|
|
+ ;
|
|
|
+ public AlgorithmFrameworkFlex() {
|
|
|
+ content.setLayout(new BorderLayout());
|
|
|
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
|
|
|
+ createOptionPanel(), console);
|
|
|
+ splitPane.setResizeWeight(0.0);
|
|
|
+ content.add(splitPane, BorderLayout.CENTER);
|
|
|
+ content.setPreferredSize(new Dimension(1200, 800));
|
|
|
+ }
|
|
|
|
|
|
+ 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);
|
|
|
|
|
|
- protected abstract Individual executeAlgo();
|
|
|
+ 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 useSmartMeter = new JCheckBox("SmartMeter");
|
|
|
+ useSmartMeter.setSelected(algoUseFlexes);
|
|
|
+ useSmartMeter.setBounds(900, 130, 185, 20);
|
|
|
+ useSmartMeter.addActionListener(actionEvent ->
|
|
|
+ {
|
|
|
+ cancel();
|
|
|
+ reset();
|
|
|
+ algoUseKillSwitch = useSmartMeter.isSelected();
|
|
|
+ });
|
|
|
+ parameterPanel.add(useSmartMeter);
|
|
|
|
|
|
+ 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(Import.loadImage(ImagePreference.Button.Settings, 16, 16)));
|
|
|
+ emailSettingsButton.setBounds(1030, 200, 20, 20);
|
|
|
+ emailSettingsButton.addActionListener(event -> {
|
|
|
+ EmailNotification.OpenEmailSettings(content);
|
|
|
+ });
|
|
|
+ parameterPanel.add(emailSettingsButton);
|
|
|
|
|
|
- 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.getModel().setCurrentIteration(0);
|
|
|
- updateVisual();
|
|
|
- }else {
|
|
|
- console.println("No run inistialized.");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * To let the User See the current state without touching the Canvas.
|
|
|
- */
|
|
|
- private void updateVisual() {
|
|
|
- control.calculateStateForCurrentIteration();
|
|
|
- }
|
|
|
- /**
|
|
|
- * 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.resetSimulation();
|
|
|
- int i = 0;
|
|
|
- for(Boolean bool: position) {
|
|
|
- access.get(i++).setState(bool);
|
|
|
- }
|
|
|
- control.calculateStateForCurrentIteration();
|
|
|
-}
|
|
|
+ return parameterPanel;
|
|
|
+ }
|
|
|
|
|
|
+ private JPanel createButtonPanel() {
|
|
|
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
|
|
|
|
|
- /**
|
|
|
- * 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.
|
|
|
- * @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(initialState);
|
|
|
- resetChain.add(initialState);
|
|
|
- if(algoUseFlexes) {
|
|
|
- List<Flexibility> flexList = model.getAllFlexibilities();
|
|
|
- List<Flexibility> allOfferedFLex = flexList.stream().filter(flex -> flex.getState() == FlexState.OFFERED).toList();
|
|
|
- for(Flexibility flex :allOfferedFLex){
|
|
|
- //flex.getFlex().getElement().parentObject;
|
|
|
- AccessWrapper killSwitchAccess = this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getElement().parentObject): null;;
|
|
|
- access.add(new AccessWrapper(flex, killSwitchAccess));
|
|
|
- initialState.add(false);
|
|
|
- }
|
|
|
- List<Flexibility> allInUseFLex = flexList.stream().filter(flex -> flex.getState() == FlexState.IN_USE).toList();
|
|
|
- for(Flexibility flex : allInUseFLex){
|
|
|
- AccessWrapper killSwitchAccess = this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getElement().parentObject): null;
|
|
|
- access.add(new AccessWrapper(flex, killSwitchAccess));
|
|
|
- initialState.add(true);
|
|
|
- }
|
|
|
- }
|
|
|
- //console.println(access.stream().map(Object::toString).collect(Collectors.joining(", ")));
|
|
|
- return initialState;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private void rollOutNodes(List<Boolean> positionToInit) {
|
|
|
- boolean groupNodeSelected = groupNode.isPresent();
|
|
|
- int timeStep = control.getModel().getCurrentIteration();
|
|
|
- Stream<HolonObject> holonObjects = groupNodeSelected ? groupNode.get().getAllHolonObjectsRecursive() : control.getModel().getCanvas().getAllHolonObjectsRecursive();
|
|
|
- Stream<HolonSwitch> holonSwitches = groupNodeSelected ? groupNode.get().getAllSwitchObjectsRecursive(): control.getModel().getCanvas().getAllSwitchObjectsRecursive();
|
|
|
- holonObjects.forEach(hObject -> {
|
|
|
- AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
|
|
|
- if(this.algoUseKillSwitch) {
|
|
|
- positionToInit.add(false);
|
|
|
- access.add(killSwitchAccess);
|
|
|
- accessKillSwitch.put(hObject, killSwitchAccess);
|
|
|
- }
|
|
|
- if(this.algoUseElements) {
|
|
|
- hObject.elementsStream().forEach(hE -> {
|
|
|
- positionToInit.add(hE.active);
|
|
|
- access.add(new AccessWrapper(hE, killSwitchAccess));
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- holonSwitches.forEach(sw -> {
|
|
|
- positionToInit.add(sw.getState().isClosed());
|
|
|
- access.add(new AccessWrapper(sw));
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private RunValues getRunValuesFromActualState() {
|
|
|
- RunValues val = new RunValues();
|
|
|
-
|
|
|
- GroupNode canvas = control.getModel().getCanvas();
|
|
|
- List<HolonObject> holonObjectList = canvas.getAllHolonObjectsRecursive().toList();
|
|
|
- Map<HolonObject.HolonObjectState, Long> stateMap = holonObjectList.stream().collect(Collectors.groupingBy(HolonObject::getState, Collectors.counting()));
|
|
|
- // UPDATE SUPPLY STATE
|
|
|
- val.producer = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.PRODUCER, 0L));
|
|
|
- val.overSupplied = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.OVER_SUPPLIED, 0L));
|
|
|
- val.supplied = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.SUPPLIED, 0L));
|
|
|
- val.partiallySupplied = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.PARTIALLY_SUPPLIED, 0L));
|
|
|
- val.unsupplied = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.NOT_SUPPLIED, 0L));
|
|
|
- val.passiv = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.NO_ENERGY, 0L));
|
|
|
- val.consumer = val.overSupplied + val.supplied + val.partiallySupplied + val.unsupplied;
|
|
|
- val.objects = val.consumer + val.producer + val.passiv;
|
|
|
-
|
|
|
- List<HolonElement> holonElementList = canvas.getAllHolonElements().toList();
|
|
|
- val.elements = holonElementList.size();
|
|
|
- // UPDATE ActiveInActive
|
|
|
- val.activeElements = holonElementList.stream().filter(HolonElement::isOn).count();
|
|
|
- val.consumption = canvas.getTotalConsumption();
|
|
|
- val.production = canvas.getTotalProduction();
|
|
|
- val.difference= Math.abs(val.production - val.consumption);
|
|
|
-
|
|
|
- List<Flexibility> activeFlex = holonElementList.stream().flatMap(ele -> ele.flexList.stream()).filter(flex -> flex.getState().equals(FlexState.IN_USE)).toList();
|
|
|
- Map<HolonElement.Priority, Long> priorityCounts = activeFlex.stream().collect(Collectors.groupingBy(flex -> flex.getElement().priority, Collectors.counting()));
|
|
|
- val.essentialFlex = priorityCounts.getOrDefault(HolonElement.Priority.Essential, 0L);
|
|
|
- val.highFlex = priorityCounts.getOrDefault(HolonElement.Priority.High, 0L);
|
|
|
- val.mediumFlex = priorityCounts.getOrDefault(HolonElement.Priority.Medium, 0L);
|
|
|
- val.lowFlex = priorityCounts.getOrDefault(HolonElement.Priority.Low, 0L);
|
|
|
-
|
|
|
- val.flexebilities = activeFlex.size();
|
|
|
- val.holon = control.getModel().holons.size();
|
|
|
- List<HolonSwitch> switchList = canvas.getAllSwitchObjectsRecursive().toList();
|
|
|
- val.switches = switchList.size();
|
|
|
- val.activeSwitches = (int)switchList.stream().filter(HolonSwitch::isClosed).count();
|
|
|
-
|
|
|
- DoubleSummaryStatistics overStat = holonObjectList.stream().filter(con -> con.getState().equals(HolonObject.HolonObjectState.OVER_SUPPLIED))
|
|
|
- .mapToDouble(HolonObject::getSupplyBarPercentage).summaryStatistics();
|
|
|
-
|
|
|
- DoubleSummaryStatistics partiallyStat = holonObjectList.stream().filter(con -> con.getState().equals(HolonObject.HolonObjectState.PARTIALLY_SUPPLIED))
|
|
|
- .mapToDouble(HolonObject::getSupplyBarPercentage).summaryStatistics();
|
|
|
-
|
|
|
- val.partiallyMin = RunValues.filterInf(partiallyStat.getMin());
|
|
|
- val.partiallyMax = RunValues.filterInf(partiallyStat.getMax());
|
|
|
- val.partiallyAverage = RunValues.filterInf(partiallyStat.getAverage());
|
|
|
-
|
|
|
- val.overMin = RunValues.filterInf(overStat.getMin());
|
|
|
- val.overMax = RunValues.filterInf(overStat.getMax());
|
|
|
- val.overAverage = RunValues.filterInf(overStat.getAverage());
|
|
|
- return val;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private String stringStatFromRunValues(RunValues val){
|
|
|
- return val.stringStatFromRunValues("");
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- @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());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- static 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;
|
|
|
-
|
|
|
- public static double filterInf(double value) {
|
|
|
- if(value == Double.NEGATIVE_INFINITY || value == Double.POSITIVE_INFINITY || Double.isNaN(value)) {
|
|
|
- return 0;
|
|
|
- }else {
|
|
|
- return value;
|
|
|
- }
|
|
|
- }
|
|
|
- public static String percentage(double numerator , double denominator) {
|
|
|
- if((int)denominator == 0) {
|
|
|
- return "-%";
|
|
|
- }
|
|
|
- return Format.doubleTwoPlaces(numerator) + "/" + Format.doubleTwoPlaces(denominator) + " "+ Format.doubleFixedPlaces(2,(float)numerator /(float)denominator * 100) + "%";
|
|
|
- }
|
|
|
+ JButton resetButton = new JButton("Reset");
|
|
|
+ resetButton.setToolTipText("Resets the state to the initial grid configuration.");
|
|
|
+ resetButton.addActionListener(actionEvent -> reset());
|
|
|
+ buttonPanel.add(resetButton);
|
|
|
|
|
|
- public String stringStatFromRunValues(String prefix) {
|
|
|
- return prefix +"Passiv: " + percentage(passiv, objects)
|
|
|
- + " " + prefix +"Producer: " + percentage(producer, objects)
|
|
|
- + " " + prefix +"Consumer: " + percentage(consumer, objects)
|
|
|
- + " " + prefix +"Unsupplied: " + percentage(unsupplied, objects)
|
|
|
- + " " + prefix +"Partially: " + percentage(partiallySupplied, objects)
|
|
|
- + " " + prefix +"Over: " + percentage(overSupplied, objects)
|
|
|
- + " " + prefix +"Supplied: " + percentage(supplied, objects)
|
|
|
- + " " + prefix +"Partially.SupplyPercentage.Min: " + Format.doubleFixedPlaces(2, partiallyMin)
|
|
|
- + " " + prefix +"Partially.SupplyPercentage.Max: "+ Format.doubleFixedPlaces(2, partiallyMax)
|
|
|
- + " " + prefix +"Partially.SupplyPercentage.Average: " + Format.doubleFixedPlaces(2, partiallyAverage)
|
|
|
- + " " + prefix +"Over.SupplyPercentage.Min: " + Format.doubleFixedPlaces(2, overMin)
|
|
|
- + " " + prefix +"Over.SupplyPercentage.Max: "+ Format.doubleFixedPlaces(2, overMax)
|
|
|
- + " " + prefix +"Over.SupplyPercentage.Average: " + Format.doubleFixedPlaces(2, overAverage)
|
|
|
- + " " + prefix +"HolonElemnts.Active:" + percentage(activeElements, elements)
|
|
|
- + " " + prefix +"Flexibilities.Essential: " + percentage(essentialFlex, flexebilities)
|
|
|
- + " " + prefix +"Flexibilities.High: " + percentage(highFlex, flexebilities)
|
|
|
- + " " + prefix +"Flexibilities.Medium: " + percentage(mediumFlex, flexebilities)
|
|
|
- + " " + prefix +"Flexibilities.Low: " + percentage(lowFlex, flexebilities)
|
|
|
- + " " + prefix +"Switches.Active:" + percentage(activeSwitches,switches)
|
|
|
- + " " + prefix +"Holons: " + holon
|
|
|
- + " " + prefix +"TotalConsumption: " + consumption
|
|
|
- + " " + prefix +"TotalProduction: " + production
|
|
|
- + " " + prefix +"Difference: " + difference;
|
|
|
+ JButton cancelButton = new JButton("Cancel Run");
|
|
|
+ cancelButton.addActionListener(actionEvent -> cancel());
|
|
|
+ buttonPanel.add(cancelButton);
|
|
|
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- 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>();
|
|
|
- hObject.elementsStream().forEach(hE -> {
|
|
|
- intialStatesOfElementForKilllSwitch.add(hE.active);
|
|
|
- });
|
|
|
- }
|
|
|
- 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.active = state;
|
|
|
- }
|
|
|
- break;
|
|
|
- case Switch:
|
|
|
- hSwitch.setMode(SwitchMode.Manual);
|
|
|
- hSwitch.setManualState(state ? SwitchState.Closed: SwitchState.Open);
|
|
|
- break;
|
|
|
- case Flexibility:
|
|
|
- if(state && (!algoUseKillSwitch || (algoUseKillSwitch && !correspondingKillSwitch.getLastState()))) {
|
|
|
- flex.order();
|
|
|
- }
|
|
|
- break;
|
|
|
- case KillSwitch:
|
|
|
- if(state) {
|
|
|
- hObject.elementsStream().forEach(hE -> {
|
|
|
- hE.active = false;
|
|
|
- });
|
|
|
- }else {
|
|
|
- List<HolonElement> eleList = hObject.elementsStream().toList();
|
|
|
- for(int i = 0; i < eleList.size(); i++) {
|
|
|
- eleList.get(i).active = intialStatesOfElementForKilllSwitch.get(i);
|
|
|
- }
|
|
|
- }
|
|
|
+ JButton fitnessButton = new JButton("Evaluate");
|
|
|
+ fitnessButton.setToolTipText("Evaluate the current grid configuration.");
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ //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);
|
|
|
+ }
|
|
|
+
|
|
|
+ //ParameterImports
|
|
|
+
|
|
|
+ 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("Step size: ");
|
|
|
+ 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("Step size: ");
|
|
|
+ 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 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.getModel().getCanvas().getAllGroupNodeObjectsRecursive()
|
|
|
+ .toArray();
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ GroupNode selected = (GroupNode) 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);
|
|
|
+ groupNode = Optional.of(selected);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected double evaluatePosition(List<Boolean> positionToEvaluate) {
|
|
|
+ runProgressbar.step();
|
|
|
+ setState(positionToEvaluate); // execution time critical
|
|
|
+ double result = evaluateState();
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private double evaluateState() {
|
|
|
+ switch (this.evaluationFunction) {
|
|
|
+ case Switch:
|
|
|
+ return SwitchObjectiveFunction.getFitnessValueForState(control.getModel());
|
|
|
+ case Normal:
|
|
|
+ default:
|
|
|
+ return ObjectiveFunctionByCarlos.getFitnessValueForState(control.getModel());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void run() {
|
|
|
+ cancel = false;
|
|
|
+ control.guiSetEnabled(false);
|
|
|
+ runPrinter.openStream();
|
|
|
+ runPrinter.println("");
|
|
|
+ runPrinter.println("Start:" + stringStatFromRunValues(getRunValuesFromActualState()));
|
|
|
+ runPrinter.closeStream();
|
|
|
+ if (this.useStepping) {
|
|
|
+ initParameterStepping();
|
|
|
+ do {
|
|
|
+ executeAlgoWithParameter();
|
|
|
+ if (cancel) {
|
|
|
break;
|
|
|
- default:
|
|
|
+ }
|
|
|
+ resetState();
|
|
|
+ } while (updateOneParameter());
|
|
|
+ resetParameterStepping();
|
|
|
+ } else {
|
|
|
+ executeAlgoWithParameter();
|
|
|
+
|
|
|
+ }
|
|
|
+ updateVisual();
|
|
|
+ runProgressbar.finishedCancel();
|
|
|
+ control.guiSetEnabled(true);
|
|
|
+ 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;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- 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";
|
|
|
+ long executionTime = printElapsedTime();
|
|
|
+ setState(roundBest.position);
|
|
|
+ runPrinter.openStream();
|
|
|
+ runPrinter.println(runList.stream().map(value -> Format.doubleFixedPlaces(2, value))
|
|
|
+ .collect(Collectors.joining(", ")));
|
|
|
+ RunValues val = getRunValuesFromActualState();
|
|
|
+ val.result = roundBest.fitness;
|
|
|
+ val.executionTime = executionTime;
|
|
|
+ avg.addRun(val);
|
|
|
+ runPrinter.println(
|
|
|
+ "Result: " + Format.doubleFixedPlaces(2, roundBest.fitness) + " ExecutionTime:"
|
|
|
+ + executionTime + " " + stringStatFromRunValues(val));
|
|
|
+ runPrinter.closeStream();
|
|
|
+ resetState();
|
|
|
+ if (roundBest.fitness < runBest.fitness) {
|
|
|
+ runBest = roundBest;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ this.extractPositionAndAccess();
|
|
|
+ setState(runBest.position);
|
|
|
+ updateVisual();
|
|
|
+ console.println("Start: " + Format.doubleFixedPlaces(2, startFitness));
|
|
|
+ console.println("AlgoResult: " + Format.doubleFixedPlaces(2, runBest.fitness));
|
|
|
+ if (this.algoUseFlexes) {
|
|
|
+ calculateAndPrintFlexInfos();
|
|
|
}
|
|
|
-
|
|
|
- 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");
|
|
|
+ runPrinter.openStream();
|
|
|
+ if (rounds > 1) {
|
|
|
+ RunValues avgRun = avg.getAverage();
|
|
|
+
|
|
|
+ runPrinter.println("Average.Result: " + Format.doubleFixedPlaces(2, avgRun.result)
|
|
|
+ + " Average.ExecutionTime:" + avgRun.executionTime + " " + avg.getAverage()
|
|
|
+ .stringStatFromRunValues("Average."));
|
|
|
+ }
|
|
|
+ runPrinter.println("");
|
|
|
+ runPrinter.closeStream();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void calculateAndPrintFlexInfos() {
|
|
|
+ int amountOfUsedFlex = 0;
|
|
|
+ List<Flexibility> allFlex = control.getModel().getAllFlexibilities();
|
|
|
+ int amountOfFlex = allFlex.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;
|
|
|
+ Stream<Flexibility> allFlexInUse = allFlex.stream()
|
|
|
+ .filter(flex -> flex.getState().equals(FlexState.IN_USE));
|
|
|
+ Iterator<Flexibility> iterInUseFlex = allFlexInUse.iterator();
|
|
|
+ while (iterInUseFlex.hasNext()) {
|
|
|
+ Flexibility flex = iterInUseFlex.next();
|
|
|
+ amountOfUsedFlex++;
|
|
|
+ cost += flex.cost;
|
|
|
+ float energy = flex.energyReleased();
|
|
|
+ if (energy < 0) {
|
|
|
+ consumingFlex++;
|
|
|
+ consumingFlexEnergy += -energy;
|
|
|
+ } else {
|
|
|
+ producingFlex++;
|
|
|
+ producingFlexEnergy += energy;
|
|
|
+ }
|
|
|
+ if (flex.getCooldown() > maxCooldown) {
|
|
|
+ maxCooldown = flex.getCooldown();
|
|
|
}
|
|
|
- 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 ++;
|
|
|
+ switch (flex.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.getModel().setCurrentIteration(0);
|
|
|
+ updateVisual();
|
|
|
+ } else {
|
|
|
+ console.println("No run inistialized.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * To let the User See the current state without touching the Canvas.
|
|
|
+ */
|
|
|
+ private void updateVisual() {
|
|
|
+ control.updateStateForCurrentIteration();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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.resetSimulation();
|
|
|
+ int i = 0;
|
|
|
+ for (Boolean bool : position) {
|
|
|
+ access.get(i++).setState(bool);
|
|
|
+ }
|
|
|
+ control.calculateStateForCurrentIteration();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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.
|
|
|
+ *
|
|
|
+ * @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(initialState);
|
|
|
+ resetChain.add(initialState);
|
|
|
+ if (algoUseFlexes) {
|
|
|
+ List<Flexibility> flexList = model.getAllFlexibilities();
|
|
|
+ List<Flexibility> allOfferedFLex = flexList.stream()
|
|
|
+ .filter(flex -> flex.getState() == FlexState.OFFERED).toList();
|
|
|
+ for (Flexibility flex : allOfferedFLex) {
|
|
|
+ //flex.getFlex().getElement().parentObject;
|
|
|
+ AccessWrapper killSwitchAccess =
|
|
|
+ this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getElement().parentObject)
|
|
|
+ : null;
|
|
|
+ ;
|
|
|
+ access.add(new AccessWrapper(flex, killSwitchAccess));
|
|
|
+ initialState.add(false);
|
|
|
+ }
|
|
|
+ List<Flexibility> allInUseFLex = flexList.stream()
|
|
|
+ .filter(flex -> flex.getState() == FlexState.IN_USE).toList();
|
|
|
+ for (Flexibility flex : allInUseFLex) {
|
|
|
+ AccessWrapper killSwitchAccess =
|
|
|
+ this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getElement().parentObject)
|
|
|
+ : null;
|
|
|
+ access.add(new AccessWrapper(flex, killSwitchAccess));
|
|
|
+ initialState.add(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //console.println(access.stream().map(Object::toString).collect(Collectors.joining(", ")));
|
|
|
+ return initialState;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void rollOutNodes(List<Boolean> positionToInit) {
|
|
|
+ boolean groupNodeSelected = groupNode.isPresent();
|
|
|
+ int timeStep = control.getModel().getCurrentIteration();
|
|
|
+ Stream<HolonObject> holonObjects =
|
|
|
+ groupNodeSelected ? groupNode.get().getAllHolonObjectsRecursive()
|
|
|
+ : control.getModel().getCanvas().getAllHolonObjectsRecursive();
|
|
|
+ Stream<HolonSwitch> holonSwitches =
|
|
|
+ groupNodeSelected ? groupNode.get().getAllSwitchObjectsRecursive()
|
|
|
+ : control.getModel().getCanvas().getAllSwitchObjectsRecursive();
|
|
|
+ holonObjects.forEach(hObject -> {
|
|
|
+ AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
|
|
|
+ if (this.algoUseKillSwitch) {
|
|
|
+ positionToInit.add(false);
|
|
|
+ access.add(killSwitchAccess);
|
|
|
+ accessKillSwitch.put(hObject, killSwitchAccess);
|
|
|
+ }
|
|
|
+ if (this.algoUseElements) {
|
|
|
+ hObject.elementsStream().forEach(hE -> {
|
|
|
+ positionToInit.add(hE.active);
|
|
|
+ access.add(new AccessWrapper(hE, killSwitchAccess));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ holonSwitches.forEach(sw -> {
|
|
|
+ positionToInit.add(sw.getState().isClosed());
|
|
|
+ access.add(new AccessWrapper(sw));
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private RunValues getRunValuesFromActualState() {
|
|
|
+ RunValues val = new RunValues();
|
|
|
+
|
|
|
+ GroupNode canvas = control.getModel().getCanvas();
|
|
|
+ List<HolonObject> holonObjectList = canvas.getAllHolonObjectsRecursive().toList();
|
|
|
+ Map<HolonObject.HolonObjectState, Long> stateMap = holonObjectList.stream()
|
|
|
+ .collect(Collectors.groupingBy(HolonObject::getState, Collectors.counting()));
|
|
|
+ // UPDATE SUPPLY STATE
|
|
|
+ val.producer = Math.toIntExact(
|
|
|
+ stateMap.getOrDefault(HolonObject.HolonObjectState.PRODUCER, 0L));
|
|
|
+ val.overSupplied = Math.toIntExact(
|
|
|
+ stateMap.getOrDefault(HolonObject.HolonObjectState.OVER_SUPPLIED, 0L));
|
|
|
+ val.supplied = Math.toIntExact(
|
|
|
+ stateMap.getOrDefault(HolonObject.HolonObjectState.SUPPLIED, 0L));
|
|
|
+ val.partiallySupplied = Math.toIntExact(
|
|
|
+ stateMap.getOrDefault(HolonObject.HolonObjectState.PARTIALLY_SUPPLIED, 0L));
|
|
|
+ val.unsupplied = Math.toIntExact(
|
|
|
+ stateMap.getOrDefault(HolonObject.HolonObjectState.NOT_SUPPLIED, 0L));
|
|
|
+ val.passiv = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.NO_ENERGY, 0L));
|
|
|
+ val.consumer = val.overSupplied + val.supplied + val.partiallySupplied + val.unsupplied;
|
|
|
+ val.objects = val.consumer + val.producer + val.passiv;
|
|
|
+
|
|
|
+ List<HolonElement> holonElementList = canvas.getAllHolonElements().toList();
|
|
|
+ val.elements = holonElementList.size();
|
|
|
+ // UPDATE ActiveInActive
|
|
|
+ val.activeElements = holonElementList.stream().filter(HolonElement::isOn).count();
|
|
|
+ val.consumption = canvas.getTotalConsumption();
|
|
|
+ val.production = canvas.getTotalProduction();
|
|
|
+ val.difference = Math.abs(val.production - val.consumption);
|
|
|
+
|
|
|
+ List<Flexibility> activeFlex = holonElementList.stream().flatMap(ele -> ele.flexList.stream())
|
|
|
+ .filter(flex -> flex.getState().equals(FlexState.IN_USE)).toList();
|
|
|
+ Map<HolonElement.Priority, Long> priorityCounts = activeFlex.stream()
|
|
|
+ .collect(Collectors.groupingBy(flex -> flex.getElement().priority, Collectors.counting()));
|
|
|
+ val.essentialFlex = priorityCounts.getOrDefault(HolonElement.Priority.Essential, 0L);
|
|
|
+ val.highFlex = priorityCounts.getOrDefault(HolonElement.Priority.High, 0L);
|
|
|
+ val.mediumFlex = priorityCounts.getOrDefault(HolonElement.Priority.Medium, 0L);
|
|
|
+ val.lowFlex = priorityCounts.getOrDefault(HolonElement.Priority.Low, 0L);
|
|
|
+
|
|
|
+ val.flexebilities = activeFlex.size();
|
|
|
+ val.holon = control.getModel().holons.size();
|
|
|
+ List<HolonSwitch> switchList = canvas.getAllSwitchObjectsRecursive().toList();
|
|
|
+ val.switches = switchList.size();
|
|
|
+ val.activeSwitches = (int) switchList.stream().filter(HolonSwitch::isClosed).count();
|
|
|
+
|
|
|
+ DoubleSummaryStatistics overStat = holonObjectList.stream()
|
|
|
+ .filter(con -> con.getState().equals(HolonObject.HolonObjectState.OVER_SUPPLIED))
|
|
|
+ .mapToDouble(HolonObject::getSupplyBarPercentage).summaryStatistics();
|
|
|
+
|
|
|
+ DoubleSummaryStatistics partiallyStat = holonObjectList.stream()
|
|
|
+ .filter(con -> con.getState().equals(HolonObject.HolonObjectState.PARTIALLY_SUPPLIED))
|
|
|
+ .mapToDouble(HolonObject::getSupplyBarPercentage).summaryStatistics();
|
|
|
+
|
|
|
+ val.partiallyMin = RunValues.filterInf(partiallyStat.getMin());
|
|
|
+ val.partiallyMax = RunValues.filterInf(partiallyStat.getMax());
|
|
|
+ val.partiallyAverage = RunValues.filterInf(partiallyStat.getAverage());
|
|
|
+
|
|
|
+ val.overMin = RunValues.filterInf(overStat.getMin());
|
|
|
+ val.overMax = RunValues.filterInf(overStat.getMax());
|
|
|
+ val.overAverage = RunValues.filterInf(overStat.getAverage());
|
|
|
+ return val;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String stringStatFromRunValues(RunValues val) {
|
|
|
+ return val.stringStatFromRunValues("");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public JPanel getPanel() {
|
|
|
+ return content;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setController(Control control) {
|
|
|
+ this.control = control;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected abstract int getProgressBarMaxCount();
|
|
|
+
|
|
|
+ protected abstract String algoInformationToPrint();
|
|
|
+
|
|
|
+ protected abstract String plottFileName();
|
|
|
+
|
|
|
+ //ObjectiveFunction
|
|
|
+ enum ObjectiveFunction {Normal, Switch}
|
|
|
+
|
|
|
+ private enum AccessType {None, HolonElement, Switch, Flexibility, KillSwitch}
|
|
|
+
|
|
|
+ static 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;
|
|
|
+
|
|
|
+ public static double filterInf(double value) {
|
|
|
+ if (value == Double.NEGATIVE_INFINITY || value == Double.POSITIVE_INFINITY || Double.isNaN(
|
|
|
+ value)) {
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static String percentage(double numerator, double denominator) {
|
|
|
+ if ((int) denominator == 0) {
|
|
|
+ return "-%";
|
|
|
+ }
|
|
|
+ return Format.doubleTwoPlaces(numerator) + "/" + Format.doubleTwoPlaces(denominator) + " "
|
|
|
+ + Format.doubleFixedPlaces(2, (float) numerator / (float) denominator * 100) + "%";
|
|
|
+ }
|
|
|
+
|
|
|
+ public String stringStatFromRunValues(String prefix) {
|
|
|
+ return prefix + "Passiv: " + percentage(passiv, objects)
|
|
|
+ + " " + prefix + "Producer: " + percentage(producer, objects)
|
|
|
+ + " " + prefix + "Consumer: " + percentage(consumer, objects)
|
|
|
+ + " " + prefix + "Unsupplied: " + percentage(unsupplied, objects)
|
|
|
+ + " " + prefix + "Partially: " + percentage(partiallySupplied, objects)
|
|
|
+ + " " + prefix + "Over: " + percentage(overSupplied, objects)
|
|
|
+ + " " + prefix + "Supplied: " + percentage(supplied, objects)
|
|
|
+ + " " + prefix + "Partially.SupplyPercentage.Min: " + Format.doubleFixedPlaces(2,
|
|
|
+ partiallyMin)
|
|
|
+ + " " + prefix + "Partially.SupplyPercentage.Max: " + Format.doubleFixedPlaces(2,
|
|
|
+ partiallyMax)
|
|
|
+ + " " + prefix + "Partially.SupplyPercentage.Average: " + Format.doubleFixedPlaces(2,
|
|
|
+ partiallyAverage)
|
|
|
+ + " " + prefix + "Over.SupplyPercentage.Min: " + Format.doubleFixedPlaces(2, overMin)
|
|
|
+ + " " + prefix + "Over.SupplyPercentage.Max: " + Format.doubleFixedPlaces(2, overMax)
|
|
|
+ + " " + prefix + "Over.SupplyPercentage.Average: " + Format.doubleFixedPlaces(2,
|
|
|
+ overAverage)
|
|
|
+ + " " + prefix + "HolonElemnts.Active:" + percentage(activeElements, elements)
|
|
|
+ + " " + prefix + "Flexibilities.Essential: " + percentage(essentialFlex, flexebilities)
|
|
|
+ + " " + prefix + "Flexibilities.High: " + percentage(highFlex, flexebilities)
|
|
|
+ + " " + prefix + "Flexibilities.Medium: " + percentage(mediumFlex, flexebilities)
|
|
|
+ + " " + prefix + "Flexibilities.Low: " + percentage(lowFlex, flexebilities)
|
|
|
+ + " " + prefix + "Switches.Active:" + percentage(activeSwitches, switches)
|
|
|
+ + " " + prefix + "Holons: " + holon
|
|
|
+ + " " + prefix + "TotalConsumption: " + consumption
|
|
|
+ + " " + prefix + "TotalProduction: " + production
|
|
|
+ + " " + prefix + "Difference: " + difference;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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 RunProgressBar {
|
|
|
+
|
|
|
+ //progressbar
|
|
|
+ private JProgressBar progressBar = new JProgressBar();
|
|
|
+ private int count = 0;
|
|
|
+ private boolean isActive = false;
|
|
|
+
|
|
|
+ public void step() {
|
|
|
+ if (isActive) {
|
|
|
+ progressBar.setValue(count++);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- void reset() {
|
|
|
- setter.accept(startValue);
|
|
|
- count = 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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>();
|
|
|
+ hObject.elementsStream().forEach(hE -> {
|
|
|
+ intialStatesOfElementForKilllSwitch.add(hE.active);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ 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.active = state;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case Switch:
|
|
|
+ hSwitch.setMode(SwitchMode.Manual);
|
|
|
+ hSwitch.setManualState(state ? SwitchState.Closed : SwitchState.Open);
|
|
|
+ break;
|
|
|
+ case Flexibility:
|
|
|
+ if (state && (!algoUseKillSwitch || (algoUseKillSwitch
|
|
|
+ && !correspondingKillSwitch.getLastState()))) {
|
|
|
+ flex.order();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case KillSwitch:
|
|
|
+ if (state) {
|
|
|
+ hObject.elementsStream().forEach(hE -> {
|
|
|
+ hE.active = false;
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ List<HolonElement> eleList = hObject.elementsStream().toList();
|
|
|
+ for (int i = 0; i < eleList.size(); i++) {
|
|
|
+ eleList.get(i).active = 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() + "]";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+ int stepps;
|
|
|
+ T stepSize;
|
|
|
+ T startValue;
|
|
|
+ Consumer<T> setter;
|
|
|
+ Supplier<T> getter;
|
|
|
+ BiFunction<Integer, T, T> multyply;
|
|
|
+ BiFunction<T, T, T> add;
|
|
|
+ private int count = 0;
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|