AlgorithmFrameworkFlex.java 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386
  1. package holeg.api;
  2. import holeg.addon.helper.EmailNotification;
  3. import holeg.algorithm.objective_function.ObjectiveFunctionByCarlos;
  4. import holeg.algorithm.objective_function.SwitchObjectiveFunction;
  5. import holeg.model.Flexibility;
  6. import holeg.model.Flexibility.FlexState;
  7. import holeg.model.GroupNode;
  8. import holeg.model.HolonElement;
  9. import holeg.model.HolonObject;
  10. import holeg.model.HolonSwitch;
  11. import holeg.model.HolonSwitch.SwitchMode;
  12. import holeg.model.HolonSwitch.SwitchState;
  13. import holeg.model.Model;
  14. import holeg.preferences.ImagePreference;
  15. import holeg.ui.controller.Control;
  16. import holeg.ui.view.component.Console;
  17. import holeg.ui.view.image.Import;
  18. import holeg.utility.math.decimal.Format;
  19. import java.awt.BorderLayout;
  20. import java.awt.Component;
  21. import java.awt.Dimension;
  22. import java.awt.FlowLayout;
  23. import java.awt.image.BufferedImage;
  24. import java.io.BufferedWriter;
  25. import java.io.File;
  26. import java.io.FileOutputStream;
  27. import java.io.IOException;
  28. import java.io.OutputStreamWriter;
  29. import java.math.RoundingMode;
  30. import java.text.NumberFormat;
  31. import java.util.ArrayList;
  32. import java.util.Collections;
  33. import java.util.DoubleSummaryStatistics;
  34. import java.util.HashMap;
  35. import java.util.Iterator;
  36. import java.util.LinkedList;
  37. import java.util.List;
  38. import java.util.Locale;
  39. import java.util.Map;
  40. import java.util.Optional;
  41. import java.util.function.BiFunction;
  42. import java.util.function.Consumer;
  43. import java.util.function.Supplier;
  44. import java.util.stream.Collectors;
  45. import java.util.stream.Stream;
  46. import javax.swing.BorderFactory;
  47. import javax.swing.Box;
  48. import javax.swing.BoxLayout;
  49. import javax.swing.ImageIcon;
  50. import javax.swing.JButton;
  51. import javax.swing.JCheckBox;
  52. import javax.swing.JComboBox;
  53. import javax.swing.JFileChooser;
  54. import javax.swing.JFormattedTextField;
  55. import javax.swing.JLabel;
  56. import javax.swing.JOptionPane;
  57. import javax.swing.JPanel;
  58. import javax.swing.JProgressBar;
  59. import javax.swing.JScrollPane;
  60. import javax.swing.JSplitPane;
  61. import javax.swing.text.NumberFormatter;
  62. public abstract class AlgorithmFrameworkFlex implements AddOn {
  63. //Algo
  64. protected int rounds = 1;
  65. protected Console console = new Console();
  66. protected boolean cancel = false;
  67. //holeg interaction
  68. protected Control control;
  69. protected List<Double> runList = new LinkedList<Double>();
  70. protected boolean useStepping = false;
  71. LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
  72. boolean algoUseElements = false, algoUseSwitches = true, algoUseFlexes = true, algoUseKillSwitch = true;
  73. //Parameter
  74. @SuppressWarnings("rawtypes")
  75. LinkedList<ParameterStepping> parameterSteppingList = new LinkedList<ParameterStepping>();
  76. ObjectiveFunction evaluationFunction = ObjectiveFunction.Normal;
  77. //Panel
  78. private JPanel content = new JPanel();
  79. private JPanel borderPanel = new JPanel();
  80. //Settings groupNode
  81. private Optional<GroupNode> groupNode = Optional.empty();
  82. //access
  83. private ArrayList<AccessWrapper> access;
  84. private HashMap<HolonObject, AccessWrapper> accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
  85. //time
  86. private long startTime;
  87. private RunProgressBar runProgressbar = new RunProgressBar();
  88. //concurrency
  89. private Thread runThread = new Thread();
  90. //printing
  91. private Printer runPrinter = new Printer(plottFileName());
  92. private RunAverage avg = new RunAverage();
  93. //Email
  94. private boolean useEmailNotification = false;
  95. ;
  96. public AlgorithmFrameworkFlex() {
  97. content.setLayout(new BorderLayout());
  98. JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
  99. createOptionPanel(), console);
  100. splitPane.setResizeWeight(0.0);
  101. content.add(splitPane, BorderLayout.CENTER);
  102. content.setPreferredSize(new Dimension(1200, 800));
  103. }
  104. private JPanel createOptionPanel() {
  105. JPanel optionPanel = new JPanel(new BorderLayout());
  106. JScrollPane scrollPane = new JScrollPane(createParameterPanel());
  107. scrollPane.setBorder(BorderFactory.createTitledBorder("Parameter"));
  108. optionPanel.add(scrollPane, BorderLayout.CENTER);
  109. optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
  110. return optionPanel;
  111. }
  112. private Component createParameterPanel() {
  113. JPanel parameterPanel = new JPanel(null);
  114. parameterPanel.setPreferredSize(new Dimension(510, 300));
  115. borderPanel.setLayout(new BoxLayout(borderPanel, BoxLayout.PAGE_AXIS));
  116. addIntParameter("Rounds", rounds, intInput -> rounds = intInput, () -> rounds, 1);
  117. JScrollPane scrollPane = new JScrollPane(borderPanel);
  118. scrollPane.setBounds(10, 0, 850, 292);
  119. scrollPane.setBorder(BorderFactory.createEmptyBorder());
  120. parameterPanel.add(scrollPane);
  121. JButton selectGroupNodeButton = new JButton("Select GroupNode");
  122. selectGroupNodeButton.setBounds(900, 0, 185, 30);
  123. selectGroupNodeButton.addActionListener(actionEvent -> selectGroupNode());
  124. parameterPanel.add(selectGroupNodeButton);
  125. JProgressBar progressBar = runProgressbar.getJProgressBar();
  126. progressBar.setBounds(900, 35, 185, 20);
  127. progressBar.setStringPainted(true);
  128. parameterPanel.add(progressBar);
  129. JCheckBox useElements = new JCheckBox("Elements");
  130. useElements.setSelected(algoUseElements);
  131. useElements.setBounds(900, 70, 185, 20);
  132. useElements.addActionListener(actionEvent -> algoUseElements = useElements.isSelected());
  133. parameterPanel.add(useElements);
  134. JCheckBox useSwitches = new JCheckBox("Switches");
  135. useSwitches.setSelected(algoUseSwitches);
  136. useSwitches.setBounds(900, 90, 185, 20);
  137. useSwitches.addActionListener(actionEvent -> algoUseSwitches = useSwitches.isSelected());
  138. parameterPanel.add(useSwitches);
  139. JCheckBox useFlexes = new JCheckBox("Flexibilities");
  140. useFlexes.setSelected(algoUseFlexes);
  141. useFlexes.setBounds(900, 110, 185, 20);
  142. useFlexes.addActionListener(actionEvent -> algoUseFlexes = useFlexes.isSelected());
  143. parameterPanel.add(useFlexes);
  144. JCheckBox useSmartMeter = new JCheckBox("SmartMeter");
  145. useSmartMeter.setSelected(algoUseFlexes);
  146. useSmartMeter.setBounds(900, 130, 185, 20);
  147. useSmartMeter.addActionListener(actionEvent ->
  148. {
  149. cancel();
  150. reset();
  151. algoUseKillSwitch = useSmartMeter.isSelected();
  152. });
  153. parameterPanel.add(useSmartMeter);
  154. String[] objectiveFunctionStrings = {"Normal", "Switch"};
  155. JLabel fitnessLabel = new JLabel("FitnessFunction:");
  156. fitnessLabel.setBounds(910, 160, 90, 20);
  157. parameterPanel.add(fitnessLabel);
  158. JComboBox<String> ofBox = new JComboBox<String>(objectiveFunctionStrings);
  159. ofBox.addActionListener(actionEvent ->
  160. {
  161. boolean pickNormal = ((String) ofBox.getSelectedItem()).equals("Normal");
  162. evaluationFunction = pickNormal ? ObjectiveFunction.Normal : ObjectiveFunction.Switch;
  163. });
  164. ofBox.setBounds(1000, 160, 70, 20);
  165. parameterPanel.add(ofBox);
  166. JCheckBox emailNotificationCheckbox = new JCheckBox("EmailNotification");
  167. emailNotificationCheckbox.setSelected(this.useEmailNotification);
  168. emailNotificationCheckbox.setBounds(900, 200, 130, 20);
  169. emailNotificationCheckbox.addActionListener(
  170. actionEvent -> useEmailNotification = emailNotificationCheckbox.isSelected());
  171. parameterPanel.add(emailNotificationCheckbox);
  172. JButton emailSettingsButton = new JButton("",
  173. new ImageIcon(Import.loadImage(ImagePreference.Button.Settings, 16, 16)));
  174. emailSettingsButton.setBounds(1030, 200, 20, 20);
  175. emailSettingsButton.addActionListener(event -> {
  176. EmailNotification.OpenEmailSettings(content);
  177. });
  178. parameterPanel.add(emailSettingsButton);
  179. return parameterPanel;
  180. }
  181. private JPanel createButtonPanel() {
  182. JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  183. JButton resetButton = new JButton("Reset");
  184. resetButton.setToolTipText("Resets the state to the initial grid configuration.");
  185. resetButton.addActionListener(actionEvent -> reset());
  186. buttonPanel.add(resetButton);
  187. JButton cancelButton = new JButton("Cancel Run");
  188. cancelButton.addActionListener(actionEvent -> cancel());
  189. buttonPanel.add(cancelButton);
  190. JButton fitnessButton = new JButton("Evaluate");
  191. fitnessButton.setToolTipText("Evaluate the current grid configuration.");
  192. fitnessButton.addActionListener(actionEvent -> fitness());
  193. buttonPanel.add(fitnessButton);
  194. JButton runButton = new JButton("Run");
  195. runButton.addActionListener(actionEvent -> {
  196. Runnable task = () -> run();
  197. runThread = new Thread(task);
  198. runThread.start();
  199. });
  200. buttonPanel.add(runButton);
  201. return buttonPanel;
  202. }
  203. //int
  204. protected void addIntParameter(String parameterName, int parameterValue, Consumer<Integer> setter,
  205. Supplier<Integer> getter) {
  206. this.addIntParameter(parameterName, parameterValue, setter, getter, Integer.MIN_VALUE,
  207. Integer.MAX_VALUE);
  208. }
  209. //ParameterImports
  210. protected void addIntParameter(String parameterName, int parameterValue, Consumer<Integer> setter,
  211. Supplier<Integer> getter, int parameterMinValue) {
  212. this.addIntParameter(parameterName, parameterValue, setter, getter, parameterMinValue,
  213. Integer.MAX_VALUE);
  214. }
  215. protected void addIntParameter(String parameterName, int parameterValue, Consumer<Integer> setter,
  216. Supplier<Integer> getter, int parameterMinValue, int parameterMaxValue) {
  217. JPanel singleParameterPanel = new JPanel();
  218. singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
  219. singleParameterPanel.setAlignmentX(0.0f);
  220. singleParameterPanel.add(new JLabel(parameterName + ": "));
  221. singleParameterPanel.add(Box.createHorizontalGlue());
  222. NumberFormat format = NumberFormat.getIntegerInstance();
  223. format.setGroupingUsed(false);
  224. format.setParseIntegerOnly(true);
  225. NumberFormatter integerFormatter = new NumberFormatter(format);
  226. integerFormatter.setMinimum(parameterMinValue);
  227. integerFormatter.setMaximum(parameterMaxValue);
  228. integerFormatter.setCommitsOnValidEdit(true);
  229. JFormattedTextField singleParameterTextField = new JFormattedTextField(integerFormatter);
  230. singleParameterTextField.setValue(parameterValue);
  231. String minValue = (parameterMinValue == Integer.MIN_VALUE) ? "Integer.MIN_VALUE"
  232. : String.valueOf(parameterMinValue);
  233. String maxValue = (parameterMaxValue == Integer.MAX_VALUE) ? "Integer.MAX_VALUE"
  234. : String.valueOf(parameterMaxValue);
  235. singleParameterTextField.setToolTipText(
  236. "Only integer \u2208 [" + minValue + "," + maxValue + "]");
  237. singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(
  238. Integer.parseInt(singleParameterTextField.getValue().toString())));
  239. singleParameterTextField.setMaximumSize(new Dimension(200, 30));
  240. singleParameterTextField.setPreferredSize(new Dimension(200, 30));
  241. singleParameterPanel.add(singleParameterTextField);
  242. ParameterStepping<Integer> intParameterStepping = new ParameterStepping<Integer>(setter, getter,
  243. Integer::sum, (a, b) -> a * b, 1, 1);
  244. intParameterStepping.useThisParameter = false;
  245. parameterSteppingList.add(intParameterStepping);
  246. JCheckBox useSteppingCheckBox = new JCheckBox();
  247. useSteppingCheckBox.setSelected(false);
  248. singleParameterPanel.add(useSteppingCheckBox);
  249. JLabel stepsLabel = new JLabel("Steps: ");
  250. stepsLabel.setEnabled(false);
  251. singleParameterPanel.add(stepsLabel);
  252. NumberFormatter stepFormatter = new NumberFormatter(format);
  253. stepFormatter.setMinimum(1);
  254. stepFormatter.setMaximum(Integer.MAX_VALUE);
  255. stepFormatter.setCommitsOnValidEdit(true);
  256. JFormattedTextField stepsTextField = new JFormattedTextField(stepFormatter);
  257. stepsTextField.setEnabled(false);
  258. stepsTextField.setValue(1);
  259. stepsTextField.setToolTipText("Only integer \u2208 [" + 1 + "," + Integer.MAX_VALUE + "]");
  260. stepsTextField.addPropertyChangeListener(
  261. actionEvent -> intParameterStepping.stepps = Integer.parseInt(
  262. stepsTextField.getValue().toString()));
  263. stepsTextField.setMaximumSize(new Dimension(40, 30));
  264. stepsTextField.setPreferredSize(new Dimension(40, 30));
  265. singleParameterPanel.add(stepsTextField);
  266. JLabel stepsSizeLabel = new JLabel("Step size: ");
  267. stepsSizeLabel.setEnabled(false);
  268. singleParameterPanel.add(stepsSizeLabel);
  269. JFormattedTextField stepsSizeTextField = new JFormattedTextField(stepFormatter);
  270. stepsSizeTextField.setEnabled(false);
  271. stepsSizeTextField.setValue(1);
  272. stepsSizeTextField.setToolTipText("Only integer \u2208 [" + 1 + "," + Integer.MAX_VALUE + "]");
  273. stepsSizeTextField.addPropertyChangeListener(
  274. actionEvent -> intParameterStepping.stepSize = Integer.parseInt(
  275. stepsSizeTextField.getValue().toString()));
  276. stepsSizeTextField.setMaximumSize(new Dimension(40, 30));
  277. stepsSizeTextField.setPreferredSize(new Dimension(40, 30));
  278. singleParameterPanel.add(stepsSizeTextField);
  279. useSteppingCheckBox.addActionListener(actionEvent -> {
  280. boolean enabled = useSteppingCheckBox.isSelected();
  281. intParameterStepping.useThisParameter = enabled;
  282. this.useStepping = this.parameterSteppingList.stream()
  283. .anyMatch(parameter -> parameter.useThisParameter);
  284. stepsLabel.setEnabled(enabled);
  285. stepsTextField.setEnabled(enabled);
  286. stepsSizeLabel.setEnabled(enabled);
  287. stepsSizeTextField.setEnabled(enabled);
  288. });
  289. borderPanel.add(singleParameterPanel);
  290. }
  291. //double
  292. protected void addDoubleParameter(String parameterName, double parameterValue,
  293. Consumer<Double> setter, Supplier<Double> getter) {
  294. this.addDoubleParameter(parameterName, parameterValue, setter, getter, Double.MIN_VALUE,
  295. Double.MAX_VALUE);
  296. }
  297. protected void addDoubleParameter(String parameterName, double parameterValue,
  298. Consumer<Double> setter, Supplier<Double> getter, double parameterMinValue) {
  299. this.addDoubleParameter(parameterName, parameterValue, setter, getter, parameterMinValue,
  300. Double.MAX_VALUE);
  301. }
  302. protected void addDoubleParameter(String parameterName, double parameterValue,
  303. Consumer<Double> setter, Supplier<Double> getter, double parameterMinValue,
  304. double parameterMaxValue) {
  305. JPanel singleParameterPanel = new JPanel();
  306. singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
  307. singleParameterPanel.setAlignmentX(0.0f);
  308. singleParameterPanel.add(new JLabel(parameterName + ": "));
  309. singleParameterPanel.add(Box.createHorizontalGlue());
  310. NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
  311. doubleFormat.setMinimumFractionDigits(1);
  312. doubleFormat.setMaximumFractionDigits(10);
  313. doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
  314. NumberFormatter doubleFormatter = new NumberFormatter(doubleFormat);
  315. doubleFormatter.setMinimum(parameterMinValue);
  316. doubleFormatter.setMaximum(parameterMaxValue);
  317. doubleFormatter.setCommitsOnValidEdit(true);
  318. JFormattedTextField singleParameterTextField = new JFormattedTextField(doubleFormatter);
  319. singleParameterTextField.setValue(parameterValue);
  320. String minValue = (parameterMinValue == Double.MIN_VALUE) ? "Double.MIN_VALUE"
  321. : String.valueOf(parameterMinValue);
  322. String maxValue = (parameterMaxValue == Double.MAX_VALUE) ? "Double.MAX_VALUE"
  323. : String.valueOf(parameterMaxValue);
  324. singleParameterTextField.setToolTipText(
  325. "Only double \u2208 [" + minValue + "," + maxValue + "]");
  326. singleParameterTextField.addPropertyChangeListener(actionEvent -> setter.accept(
  327. Double.parseDouble(singleParameterTextField.getValue().toString())));
  328. singleParameterTextField.setMaximumSize(new Dimension(200, 30));
  329. singleParameterTextField.setPreferredSize(new Dimension(200, 30));
  330. singleParameterPanel.add(singleParameterTextField);
  331. ParameterStepping<Double> doubleParameterStepping = new ParameterStepping<Double>(setter,
  332. getter, (a, b) -> a + b, (a, b) -> a * b, 1.0, 1);
  333. doubleParameterStepping.useThisParameter = false;
  334. parameterSteppingList.add(doubleParameterStepping);
  335. JCheckBox useSteppingCheckBox = new JCheckBox();
  336. useSteppingCheckBox.setSelected(false);
  337. singleParameterPanel.add(useSteppingCheckBox);
  338. JLabel stepsLabel = new JLabel("Steps: ");
  339. stepsLabel.setEnabled(false);
  340. singleParameterPanel.add(stepsLabel);
  341. NumberFormat format = NumberFormat.getIntegerInstance();
  342. format.setGroupingUsed(false);
  343. format.setParseIntegerOnly(true);
  344. NumberFormatter integerFormatter = new NumberFormatter(format);
  345. integerFormatter.setMinimum(1);
  346. integerFormatter.setMaximum(Integer.MAX_VALUE);
  347. integerFormatter.setCommitsOnValidEdit(true);
  348. JFormattedTextField stepsTextField = new JFormattedTextField(integerFormatter);
  349. stepsTextField.setEnabled(false);
  350. stepsTextField.setValue(1);
  351. stepsTextField.setToolTipText("Only integer \u2208 [" + 1 + "," + Integer.MAX_VALUE + "]");
  352. stepsTextField.addPropertyChangeListener(
  353. actionEvent -> doubleParameterStepping.stepps = Integer.parseInt(
  354. stepsTextField.getValue().toString()));
  355. stepsTextField.setMaximumSize(new Dimension(40, 30));
  356. stepsTextField.setPreferredSize(new Dimension(40, 30));
  357. singleParameterPanel.add(stepsTextField);
  358. JLabel stepsSizeLabel = new JLabel("Step size: ");
  359. stepsSizeLabel.setEnabled(false);
  360. singleParameterPanel.add(stepsSizeLabel);
  361. NumberFormatter doubleFormatterForStepping = new NumberFormatter(doubleFormat);
  362. doubleFormatterForStepping.setCommitsOnValidEdit(true);
  363. JFormattedTextField stepsSizeTextField = new JFormattedTextField(doubleFormatterForStepping);
  364. stepsSizeTextField.setEnabled(false);
  365. stepsSizeTextField.setValue(1.0);
  366. stepsSizeTextField.setToolTipText("Only double");
  367. stepsSizeTextField.addPropertyChangeListener(
  368. actionEvent -> doubleParameterStepping.stepSize = Double.parseDouble(
  369. stepsSizeTextField.getValue().toString()));
  370. stepsSizeTextField.setMaximumSize(new Dimension(40, 30));
  371. stepsSizeTextField.setPreferredSize(new Dimension(40, 30));
  372. singleParameterPanel.add(stepsSizeTextField);
  373. useSteppingCheckBox.addActionListener(actionEvent -> {
  374. boolean enabled = useSteppingCheckBox.isSelected();
  375. doubleParameterStepping.useThisParameter = enabled;
  376. this.useStepping = this.parameterSteppingList.stream()
  377. .anyMatch(parameter -> parameter.useThisParameter);
  378. stepsLabel.setEnabled(enabled);
  379. stepsTextField.setEnabled(enabled);
  380. stepsSizeLabel.setEnabled(enabled);
  381. stepsSizeTextField.setEnabled(enabled);
  382. });
  383. borderPanel.add(singleParameterPanel);
  384. }
  385. //boolean
  386. protected void addBooleanParameter(String parameterName, boolean parameterValue,
  387. Consumer<Boolean> setter) {
  388. JPanel singleParameterPanel = new JPanel();
  389. singleParameterPanel.setLayout(new BoxLayout(singleParameterPanel, BoxLayout.LINE_AXIS));
  390. singleParameterPanel.setAlignmentX(0.0f);
  391. singleParameterPanel.add(new JLabel(parameterName + ": "));
  392. singleParameterPanel.add(Box.createHorizontalGlue());
  393. JCheckBox useGroupNodeCheckBox = new JCheckBox();
  394. useGroupNodeCheckBox.setSelected(parameterValue);
  395. useGroupNodeCheckBox.addActionListener(
  396. actionEvent -> setter.accept(useGroupNodeCheckBox.isSelected()));
  397. singleParameterPanel.add(useGroupNodeCheckBox);
  398. borderPanel.add(singleParameterPanel);
  399. }
  400. private void startTimer() {
  401. startTime = System.currentTimeMillis();
  402. }
  403. private long printElapsedTime() {
  404. long elapsedMilliSeconds = System.currentTimeMillis() - startTime;
  405. console.println("Execution Time in Milliseconds:" + elapsedMilliSeconds);
  406. return elapsedMilliSeconds;
  407. }
  408. private void cancel() {
  409. if (runThread.isAlive()) {
  410. console.println("Cancel run.");
  411. cancel = true;
  412. runProgressbar.cancel();
  413. } else {
  414. console.println("Nothing to cancel.");
  415. }
  416. }
  417. private void fitness() {
  418. if (runThread.isAlive()) {
  419. console.println("Run have to be cancelled first.");
  420. return;
  421. }
  422. double currentFitness = evaluatePosition(extractPositionAndAccess());
  423. resetChain.removeLast();
  424. console.println("Actual Fitnessvalue: " + currentFitness);
  425. }
  426. private void selectGroupNode() {
  427. Object[] possibilities = control.getModel().getCanvas().getAllGroupNodeObjectsRecursive()
  428. .toArray();
  429. @SuppressWarnings("unchecked")
  430. GroupNode selected = (GroupNode) JOptionPane.showInputDialog(content, "Select GroupNode:",
  431. "GroupNode?", JOptionPane.OK_OPTION,
  432. new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)), possibilities, "");
  433. if (selected != null) {
  434. console.println("Selected: " + selected);
  435. groupNode = Optional.of(selected);
  436. }
  437. }
  438. protected double evaluatePosition(List<Boolean> positionToEvaluate) {
  439. runProgressbar.step();
  440. setState(positionToEvaluate); // execution time critical
  441. double result = evaluateState();
  442. return result;
  443. }
  444. private double evaluateState() {
  445. switch (this.evaluationFunction) {
  446. case Switch:
  447. return SwitchObjectiveFunction.getFitnessValueForState(control.getModel());
  448. case Normal:
  449. default:
  450. return ObjectiveFunctionByCarlos.getFitnessValueForState(control.getModel());
  451. }
  452. }
  453. private void run() {
  454. cancel = false;
  455. control.guiSetEnabled(false);
  456. runPrinter.openStream();
  457. runPrinter.println("");
  458. runPrinter.println("Start:" + stringStatFromRunValues(getRunValuesFromActualState()));
  459. runPrinter.closeStream();
  460. if (this.useStepping) {
  461. initParameterStepping();
  462. do {
  463. executeAlgoWithParameter();
  464. if (cancel) {
  465. break;
  466. }
  467. resetState();
  468. } while (updateOneParameter());
  469. resetParameterStepping();
  470. } else {
  471. executeAlgoWithParameter();
  472. }
  473. updateVisual();
  474. runProgressbar.finishedCancel();
  475. control.guiSetEnabled(true);
  476. if (this.useEmailNotification && !cancel) {
  477. EmailNotification.sendEmail(this.getClass().getName() + " finished", "Execution done.");
  478. }
  479. }
  480. @SuppressWarnings("rawtypes")
  481. private void initParameterStepping() {
  482. for (ParameterStepping param : this.parameterSteppingList) {
  483. param.init();
  484. }
  485. }
  486. @SuppressWarnings("rawtypes")
  487. private void resetParameterStepping() {
  488. for (ParameterStepping param : this.parameterSteppingList) {
  489. param.reset();
  490. }
  491. }
  492. @SuppressWarnings("rawtypes")
  493. private boolean updateOneParameter() {
  494. List<ParameterStepping> parameterInUseList = this.parameterSteppingList.stream()
  495. .filter(param -> param.useThisParameter).collect(Collectors.toList());
  496. Collections.reverse(parameterInUseList);
  497. int lastParameter = parameterInUseList.size() - 1;
  498. int actualParameter = 0;
  499. for (ParameterStepping param : parameterInUseList) {
  500. if (param.canUpdate()) {
  501. param.update();
  502. return true;
  503. } else {
  504. if (actualParameter == lastParameter) {
  505. break;
  506. }
  507. param.reset();
  508. }
  509. actualParameter++;
  510. }
  511. //No Param can be updated
  512. return false;
  513. }
  514. private void executeAlgoWithParameter() {
  515. double startFitness = evaluatePosition(extractPositionAndAccess());
  516. console.println("BitLength: " + access.size());
  517. resetChain.removeLast();
  518. runPrinter.openStream();
  519. runPrinter.println(algoInformationToPrint());
  520. console.println(algoInformationToPrint());
  521. runPrinter.closeStream();
  522. runProgressbar.start();
  523. Individual runBest = new Individual();
  524. runBest.fitness = Double.MAX_VALUE;
  525. this.avg = new RunAverage();
  526. for (int r = 0; r < rounds; r++) {
  527. startTimer();
  528. Individual roundBest = executeAlgo();
  529. if (cancel) {
  530. return;
  531. }
  532. long executionTime = printElapsedTime();
  533. setState(roundBest.position);
  534. runPrinter.openStream();
  535. runPrinter.println(runList.stream().map(value -> Format.doubleFixedPlaces(2, value))
  536. .collect(Collectors.joining(", ")));
  537. RunValues val = getRunValuesFromActualState();
  538. val.result = roundBest.fitness;
  539. val.executionTime = executionTime;
  540. avg.addRun(val);
  541. runPrinter.println(
  542. "Result: " + Format.doubleFixedPlaces(2, roundBest.fitness) + " ExecutionTime:"
  543. + executionTime + " " + stringStatFromRunValues(val));
  544. runPrinter.closeStream();
  545. resetState();
  546. if (roundBest.fitness < runBest.fitness) {
  547. runBest = roundBest;
  548. }
  549. }
  550. this.extractPositionAndAccess();
  551. setState(runBest.position);
  552. updateVisual();
  553. console.println("Start: " + Format.doubleFixedPlaces(2, startFitness));
  554. console.println("AlgoResult: " + Format.doubleFixedPlaces(2, runBest.fitness));
  555. if (this.algoUseFlexes) {
  556. calculateAndPrintFlexInfos();
  557. }
  558. runPrinter.openStream();
  559. if (rounds > 1) {
  560. RunValues avgRun = avg.getAverage();
  561. runPrinter.println("Average.Result: " + Format.doubleFixedPlaces(2, avgRun.result)
  562. + " Average.ExecutionTime:" + avgRun.executionTime + " " + avg.getAverage()
  563. .stringStatFromRunValues("Average."));
  564. }
  565. runPrinter.println("");
  566. runPrinter.closeStream();
  567. }
  568. private void calculateAndPrintFlexInfos() {
  569. int amountOfUsedFlex = 0;
  570. List<Flexibility> allFlex = control.getModel().getAllFlexibilities();
  571. int amountOfFlex = allFlex.size();
  572. float cost = 0;
  573. int consumingFlex = 0;
  574. float consumingFlexEnergy = 0.0f;
  575. int producingFlex = 0;
  576. float producingFlexEnergy = 0.0f;
  577. int maxCooldown = 0;
  578. int amountEssential = 0;
  579. int amountHigh = 0;
  580. int amountMedium = 0;
  581. int amountLow = 0;
  582. Stream<Flexibility> allFlexInUse = allFlex.stream()
  583. .filter(flex -> flex.getState().equals(FlexState.IN_USE));
  584. Iterator<Flexibility> iterInUseFlex = allFlexInUse.iterator();
  585. while (iterInUseFlex.hasNext()) {
  586. Flexibility flex = iterInUseFlex.next();
  587. amountOfUsedFlex++;
  588. cost += flex.cost;
  589. float energy = flex.energyReleased();
  590. if (energy < 0) {
  591. consumingFlex++;
  592. consumingFlexEnergy += -energy;
  593. } else {
  594. producingFlex++;
  595. producingFlexEnergy += energy;
  596. }
  597. if (flex.getCooldown() > maxCooldown) {
  598. maxCooldown = flex.getCooldown();
  599. }
  600. switch (flex.getElement().getPriority()) {
  601. case Essential:
  602. amountEssential++;
  603. break;
  604. case High:
  605. amountHigh++;
  606. break;
  607. case Low:
  608. amountLow++;
  609. break;
  610. case Medium:
  611. amountMedium++;
  612. break;
  613. default:
  614. break;
  615. }
  616. }
  617. //Total Flexibilities:
  618. //Used Flexibilities:
  619. console.println("Used Flex [" + amountOfUsedFlex + "/" + amountOfFlex + "]");
  620. //Consuming Flexibilities:
  621. console.println(
  622. consumingFlex + " consuimg flexibilities that consumed " + consumingFlexEnergy + "Energy.");
  623. //Producing Flexibilities
  624. console.println(
  625. producingFlex + " producing flexibilities that produce " + producingFlexEnergy + "Energy.");
  626. console.println(
  627. "Flex in use:\t" + "Low= " + amountLow + "\tMedium= " + amountMedium + "\tHigh= "
  628. + amountHigh + "\tEssential= " + amountEssential);
  629. //Total cost:
  630. console.println("Total Cost: " + cost);
  631. //Longest Cooldown
  632. console.println("Max Cooldown: " + maxCooldown);
  633. //
  634. }
  635. protected abstract Individual executeAlgo();
  636. private void reset() {
  637. if (runThread.isAlive()) {
  638. console.println("Run have to be cancelled First.");
  639. return;
  640. }
  641. if (!resetChain.isEmpty()) {
  642. console.println("Resetting..");
  643. setState(resetChain.getFirst());
  644. resetChain.clear();
  645. control.resetSimulation();
  646. control.getModel().setCurrentIteration(0);
  647. updateVisual();
  648. } else {
  649. console.println("No run inistialized.");
  650. }
  651. }
  652. /**
  653. * To let the User See the current state without touching the Canvas.
  654. */
  655. private void updateVisual() {
  656. control.updateStateForCurrentIteration();
  657. }
  658. /**
  659. * Sets the Model back to its original State before the LAST run.
  660. */
  661. private void resetState() {
  662. setState(resetChain.getLast());
  663. }
  664. /**
  665. * Sets the State out of the given position for calculation or to show the user.
  666. *
  667. * @param position
  668. */
  669. private void setState(List<Boolean> position) {
  670. control.resetSimulation();
  671. int i = 0;
  672. for (Boolean bool : position) {
  673. access.get(i++).setState(bool);
  674. }
  675. control.calculateStateForCurrentIteration();
  676. }
  677. /**
  678. * Method to get the current Position alias a ListOf Booleans for aktive settings on the Objects
  679. * on the Canvas. Also initialize the Access Hashmap to swap faster positions.
  680. *
  681. * @return
  682. */
  683. protected List<Boolean> extractPositionAndAccess() {
  684. Model model = control.getModel();
  685. this.accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
  686. access = new ArrayList<AccessWrapper>();
  687. List<Boolean> initialState = new ArrayList<Boolean>();
  688. rollOutNodes(initialState);
  689. resetChain.add(initialState);
  690. if (algoUseFlexes) {
  691. List<Flexibility> flexList = model.getAllFlexibilities();
  692. List<Flexibility> allOfferedFLex = flexList.stream()
  693. .filter(flex -> flex.getState() == FlexState.OFFERED).toList();
  694. for (Flexibility flex : allOfferedFLex) {
  695. //flex.getFlex().getElement().parentObject;
  696. AccessWrapper killSwitchAccess =
  697. this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getElement().parentObject)
  698. : null;
  699. ;
  700. access.add(new AccessWrapper(flex, killSwitchAccess));
  701. initialState.add(false);
  702. }
  703. List<Flexibility> allInUseFLex = flexList.stream()
  704. .filter(flex -> flex.getState() == FlexState.IN_USE).toList();
  705. for (Flexibility flex : allInUseFLex) {
  706. AccessWrapper killSwitchAccess =
  707. this.algoUseKillSwitch ? this.accessKillSwitch.get(flex.getElement().parentObject)
  708. : null;
  709. access.add(new AccessWrapper(flex, killSwitchAccess));
  710. initialState.add(true);
  711. }
  712. }
  713. //console.println(access.stream().map(Object::toString).collect(Collectors.joining(", ")));
  714. return initialState;
  715. }
  716. private void rollOutNodes(List<Boolean> positionToInit) {
  717. boolean groupNodeSelected = groupNode.isPresent();
  718. int timeStep = control.getModel().getCurrentIteration();
  719. Stream<HolonObject> holonObjects =
  720. groupNodeSelected ? groupNode.get().getAllHolonObjectsRecursive()
  721. : control.getModel().getCanvas().getAllHolonObjectsRecursive();
  722. Stream<HolonSwitch> holonSwitches =
  723. groupNodeSelected ? groupNode.get().getAllSwitchObjectsRecursive()
  724. : control.getModel().getCanvas().getAllSwitchObjectsRecursive();
  725. holonObjects.forEach(hObject -> {
  726. AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
  727. if (this.algoUseKillSwitch) {
  728. positionToInit.add(false);
  729. access.add(killSwitchAccess);
  730. accessKillSwitch.put(hObject, killSwitchAccess);
  731. }
  732. if (this.algoUseElements) {
  733. hObject.elementsStream().forEach(hE -> {
  734. positionToInit.add(hE.active);
  735. access.add(new AccessWrapper(hE, killSwitchAccess));
  736. });
  737. }
  738. });
  739. holonSwitches.forEach(sw -> {
  740. positionToInit.add(sw.getState().isClosed());
  741. access.add(new AccessWrapper(sw));
  742. });
  743. }
  744. private RunValues getRunValuesFromActualState() {
  745. RunValues val = new RunValues();
  746. GroupNode canvas = control.getModel().getCanvas();
  747. List<HolonObject> holonObjectList = canvas.getAllHolonObjectsRecursive().toList();
  748. Map<HolonObject.HolonObjectState, Long> stateMap = holonObjectList.stream()
  749. .collect(Collectors.groupingBy(HolonObject::getState, Collectors.counting()));
  750. // UPDATE SUPPLY STATE
  751. val.producer = Math.toIntExact(
  752. stateMap.getOrDefault(HolonObject.HolonObjectState.PRODUCER, 0L));
  753. val.overSupplied = Math.toIntExact(
  754. stateMap.getOrDefault(HolonObject.HolonObjectState.OVER_SUPPLIED, 0L));
  755. val.supplied = Math.toIntExact(
  756. stateMap.getOrDefault(HolonObject.HolonObjectState.SUPPLIED, 0L));
  757. val.partiallySupplied = Math.toIntExact(
  758. stateMap.getOrDefault(HolonObject.HolonObjectState.PARTIALLY_SUPPLIED, 0L));
  759. val.unsupplied = Math.toIntExact(
  760. stateMap.getOrDefault(HolonObject.HolonObjectState.NOT_SUPPLIED, 0L));
  761. val.passiv = Math.toIntExact(stateMap.getOrDefault(HolonObject.HolonObjectState.NO_ENERGY, 0L));
  762. val.consumer = val.overSupplied + val.supplied + val.partiallySupplied + val.unsupplied;
  763. val.objects = val.consumer + val.producer + val.passiv;
  764. List<HolonElement> holonElementList = canvas.getAllHolonElements().toList();
  765. val.elements = holonElementList.size();
  766. // UPDATE ActiveInActive
  767. val.activeElements = holonElementList.stream().filter(HolonElement::isOn).count();
  768. val.consumption = canvas.getTotalConsumption();
  769. val.production = canvas.getTotalProduction();
  770. val.difference = Math.abs(val.production - val.consumption);
  771. List<Flexibility> activeFlex = holonElementList.stream().flatMap(ele -> ele.flexList.stream())
  772. .filter(flex -> flex.getState().equals(FlexState.IN_USE)).toList();
  773. Map<HolonElement.Priority, Long> priorityCounts = activeFlex.stream()
  774. .collect(Collectors.groupingBy(flex -> flex.getElement().priority, Collectors.counting()));
  775. val.essentialFlex = priorityCounts.getOrDefault(HolonElement.Priority.Essential, 0L);
  776. val.highFlex = priorityCounts.getOrDefault(HolonElement.Priority.High, 0L);
  777. val.mediumFlex = priorityCounts.getOrDefault(HolonElement.Priority.Medium, 0L);
  778. val.lowFlex = priorityCounts.getOrDefault(HolonElement.Priority.Low, 0L);
  779. val.flexebilities = activeFlex.size();
  780. val.holon = control.getModel().holons.size();
  781. List<HolonSwitch> switchList = canvas.getAllSwitchObjectsRecursive().toList();
  782. val.switches = switchList.size();
  783. val.activeSwitches = (int) switchList.stream().filter(HolonSwitch::isClosed).count();
  784. DoubleSummaryStatistics overStat = holonObjectList.stream()
  785. .filter(con -> con.getState().equals(HolonObject.HolonObjectState.OVER_SUPPLIED))
  786. .mapToDouble(HolonObject::getSupplyBarPercentage).summaryStatistics();
  787. DoubleSummaryStatistics partiallyStat = holonObjectList.stream()
  788. .filter(con -> con.getState().equals(HolonObject.HolonObjectState.PARTIALLY_SUPPLIED))
  789. .mapToDouble(HolonObject::getSupplyBarPercentage).summaryStatistics();
  790. val.partiallyMin = RunValues.filterInf(partiallyStat.getMin());
  791. val.partiallyMax = RunValues.filterInf(partiallyStat.getMax());
  792. val.partiallyAverage = RunValues.filterInf(partiallyStat.getAverage());
  793. val.overMin = RunValues.filterInf(overStat.getMin());
  794. val.overMax = RunValues.filterInf(overStat.getMax());
  795. val.overAverage = RunValues.filterInf(overStat.getAverage());
  796. return val;
  797. }
  798. private String stringStatFromRunValues(RunValues val) {
  799. return val.stringStatFromRunValues("");
  800. }
  801. @Override
  802. public JPanel getPanel() {
  803. return content;
  804. }
  805. @Override
  806. public void setController(Control control) {
  807. this.control = control;
  808. }
  809. protected abstract int getProgressBarMaxCount();
  810. protected abstract String algoInformationToPrint();
  811. protected abstract String plottFileName();
  812. //ObjectiveFunction
  813. enum ObjectiveFunction {Normal, Switch}
  814. private enum AccessType {None, HolonElement, Switch, Flexibility, KillSwitch}
  815. static class RunValues {
  816. public double result;
  817. public double executionTime;
  818. public double objects;
  819. public double passiv;
  820. public double consumer;
  821. public double supplied;
  822. public double producer;
  823. public double unsupplied;
  824. public double partiallySupplied;
  825. public double overSupplied;
  826. public double partiallyMin;
  827. public double partiallyMax;
  828. public double partiallyAverage;
  829. public double overMin;
  830. public double overMax;
  831. public double overAverage;
  832. public double activeElements;
  833. public double elements;
  834. public double essentialFlex;
  835. public double highFlex;
  836. public double mediumFlex;
  837. public double lowFlex;
  838. public double flexebilities;
  839. public double switches;
  840. public double activeSwitches;
  841. public double holon;
  842. public double consumption;
  843. public double production;
  844. public double difference;
  845. public static double filterInf(double value) {
  846. if (value == Double.NEGATIVE_INFINITY || value == Double.POSITIVE_INFINITY || Double.isNaN(
  847. value)) {
  848. return 0;
  849. } else {
  850. return value;
  851. }
  852. }
  853. public static String percentage(double numerator, double denominator) {
  854. if ((int) denominator == 0) {
  855. return "-%";
  856. }
  857. return Format.doubleTwoPlaces(numerator) + "/" + Format.doubleTwoPlaces(denominator) + " "
  858. + Format.doubleFixedPlaces(2, (float) numerator / (float) denominator * 100) + "%";
  859. }
  860. public String stringStatFromRunValues(String prefix) {
  861. return prefix + "Passiv: " + percentage(passiv, objects)
  862. + " " + prefix + "Producer: " + percentage(producer, objects)
  863. + " " + prefix + "Consumer: " + percentage(consumer, objects)
  864. + " " + prefix + "Unsupplied: " + percentage(unsupplied, objects)
  865. + " " + prefix + "Partially: " + percentage(partiallySupplied, objects)
  866. + " " + prefix + "Over: " + percentage(overSupplied, objects)
  867. + " " + prefix + "Supplied: " + percentage(supplied, objects)
  868. + " " + prefix + "Partially.SupplyPercentage.Min: " + Format.doubleFixedPlaces(2,
  869. partiallyMin)
  870. + " " + prefix + "Partially.SupplyPercentage.Max: " + Format.doubleFixedPlaces(2,
  871. partiallyMax)
  872. + " " + prefix + "Partially.SupplyPercentage.Average: " + Format.doubleFixedPlaces(2,
  873. partiallyAverage)
  874. + " " + prefix + "Over.SupplyPercentage.Min: " + Format.doubleFixedPlaces(2, overMin)
  875. + " " + prefix + "Over.SupplyPercentage.Max: " + Format.doubleFixedPlaces(2, overMax)
  876. + " " + prefix + "Over.SupplyPercentage.Average: " + Format.doubleFixedPlaces(2,
  877. overAverage)
  878. + " " + prefix + "HolonElemnts.Active:" + percentage(activeElements, elements)
  879. + " " + prefix + "Flexibilities.Essential: " + percentage(essentialFlex, flexebilities)
  880. + " " + prefix + "Flexibilities.High: " + percentage(highFlex, flexebilities)
  881. + " " + prefix + "Flexibilities.Medium: " + percentage(mediumFlex, flexebilities)
  882. + " " + prefix + "Flexibilities.Low: " + percentage(lowFlex, flexebilities)
  883. + " " + prefix + "Switches.Active:" + percentage(activeSwitches, switches)
  884. + " " + prefix + "Holons: " + holon
  885. + " " + prefix + "TotalConsumption: " + consumption
  886. + " " + prefix + "TotalProduction: " + production
  887. + " " + prefix + "Difference: " + difference;
  888. }
  889. }
  890. /**
  891. * To create Random and maybe switch the random generation in the future.
  892. */
  893. protected static class Random {
  894. private static java.util.Random random = new java.util.Random();
  895. /**
  896. * True or false
  897. *
  898. * @return the random boolean.
  899. */
  900. public static boolean nextBoolean() {
  901. return random.nextBoolean();
  902. }
  903. /**
  904. * Between 0.0(inclusive) and 1.0 (exclusive)
  905. *
  906. * @return the random double.
  907. */
  908. public static double nextDouble() {
  909. return random.nextDouble();
  910. }
  911. /**
  912. * Random Int in Range [min;max[ with UniformDistirbution
  913. *
  914. * @param min
  915. * @param max
  916. * @return
  917. */
  918. public static int nextIntegerInRange(int min, int max) {
  919. int result = min;
  920. try {
  921. result = min + random.nextInt(max - min);
  922. } catch (java.lang.IllegalArgumentException e) {
  923. System.err.println("min : " + min + " max : " + max);
  924. System.err.println("max should be more then min");
  925. }
  926. return result;
  927. }
  928. }
  929. private class RunProgressBar {
  930. //progressbar
  931. private JProgressBar progressBar = new JProgressBar();
  932. private int count = 0;
  933. private boolean isActive = false;
  934. public void step() {
  935. if (isActive) {
  936. progressBar.setValue(count++);
  937. }
  938. }
  939. public void start() {
  940. progressBar.setIndeterminate(false);
  941. count = 0;
  942. isActive = true;
  943. progressBar.setValue(0);
  944. progressBar.setMaximum(getProgressBarMaxCount());
  945. }
  946. public void cancel() {
  947. isActive = false;
  948. progressBar.setIndeterminate(true);
  949. }
  950. public void finishedCancel() {
  951. progressBar.setIndeterminate(false);
  952. progressBar.setValue(0);
  953. }
  954. public JProgressBar getJProgressBar() {
  955. return progressBar;
  956. }
  957. }
  958. public class Printer {
  959. private JFileChooser fileChooser = new JFileChooser();
  960. private BufferedWriter out;
  961. public Printer(String filename) {
  962. fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
  963. fileChooser.setSelectedFile(new File(filename));
  964. }
  965. public void openStream() {
  966. File file = fileChooser.getSelectedFile();
  967. try {
  968. file.createNewFile();
  969. out = new BufferedWriter(new OutputStreamWriter(
  970. new FileOutputStream(file, true), "UTF-8"));
  971. } catch (IOException e) {
  972. System.out.println(e.getMessage());
  973. }
  974. }
  975. public void println(String stringToPrint) {
  976. try {
  977. out.write(stringToPrint);
  978. out.newLine();
  979. } catch (IOException e) {
  980. System.out.println(e.getMessage());
  981. }
  982. }
  983. public void closeStream() {
  984. try {
  985. out.close();
  986. } catch (IOException e) {
  987. System.out.println(e.getMessage());
  988. }
  989. }
  990. }
  991. ;
  992. private class RunAverage {
  993. private int runCount = 0;
  994. //Values
  995. private RunValues sum = new RunValues();
  996. public void addRun(RunValues val) {
  997. sum.result += val.result;
  998. sum.executionTime += val.executionTime;
  999. sum.passiv += val.passiv;
  1000. sum.consumer += val.consumer;
  1001. sum.producer += val.producer;
  1002. sum.unsupplied += val.unsupplied;
  1003. sum.partiallySupplied += val.partiallySupplied;
  1004. sum.overSupplied += val.overSupplied;
  1005. sum.activeElements += val.activeElements;
  1006. sum.elements += val.elements;
  1007. sum.essentialFlex += val.essentialFlex;
  1008. sum.highFlex += val.highFlex;
  1009. sum.mediumFlex += val.mediumFlex;
  1010. sum.lowFlex += val.lowFlex;
  1011. sum.flexebilities += val.flexebilities;
  1012. sum.holon += val.holon;
  1013. sum.switches += val.switches;
  1014. sum.activeSwitches += val.activeSwitches;
  1015. sum.consumption += val.consumption;
  1016. sum.production += val.production;
  1017. sum.difference += val.difference;
  1018. sum.objects += val.objects;
  1019. sum.supplied += val.supplied;
  1020. sum.partiallyMin += val.partiallyMin;
  1021. sum.partiallyMax += val.partiallyMax;
  1022. sum.partiallyAverage += val.partiallyAverage;
  1023. sum.overMin += val.overMin;
  1024. sum.overMax += val.overMax;
  1025. sum.overAverage += val.overAverage;
  1026. runCount++;
  1027. }
  1028. public RunValues getAverage() {
  1029. RunValues avg = new RunValues();
  1030. if (runCount == 0) {
  1031. return avg;
  1032. }
  1033. avg.result = sum.result / runCount;
  1034. avg.executionTime = sum.executionTime / runCount;
  1035. avg.passiv = sum.passiv / runCount;
  1036. avg.consumer = sum.consumer / runCount;
  1037. avg.producer = sum.producer / runCount;
  1038. avg.unsupplied = sum.unsupplied / runCount;
  1039. avg.partiallySupplied = sum.partiallySupplied / runCount;
  1040. avg.overSupplied = sum.overSupplied / runCount;
  1041. avg.activeElements = sum.activeElements / runCount;
  1042. avg.elements = sum.elements / runCount;
  1043. avg.essentialFlex = sum.essentialFlex / runCount;
  1044. avg.highFlex = sum.highFlex / runCount;
  1045. avg.mediumFlex = sum.mediumFlex / runCount;
  1046. avg.lowFlex = sum.lowFlex / runCount;
  1047. avg.flexebilities = sum.flexebilities / runCount;
  1048. avg.holon = sum.holon / runCount;
  1049. avg.switches = sum.switches / runCount;
  1050. avg.activeSwitches = sum.activeSwitches / runCount;
  1051. avg.consumption = sum.consumption / runCount;
  1052. avg.production = sum.production / runCount;
  1053. avg.difference = sum.difference / runCount;
  1054. avg.objects = sum.objects / runCount;
  1055. avg.supplied = sum.supplied / runCount;
  1056. avg.supplied = sum.supplied / runCount;
  1057. avg.partiallyMin = sum.partiallyMin / runCount;
  1058. avg.partiallyMax = sum.partiallyMax / runCount;
  1059. avg.partiallyAverage = sum.partiallyAverage / runCount;
  1060. avg.overMin = sum.overMin / runCount;
  1061. avg.overMax = sum.overMax / runCount;
  1062. avg.overAverage = sum.overAverage / runCount;
  1063. return avg;
  1064. }
  1065. }
  1066. /**
  1067. * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and not have to split
  1068. * the List.
  1069. */
  1070. private class AccessWrapper {
  1071. private AccessType type;
  1072. private List<Boolean> intialStatesOfElementForKilllSwitch;
  1073. private HolonObject hObject;
  1074. private HolonSwitch hSwitch;
  1075. private HolonElement hElement;
  1076. private Flexibility flex;
  1077. private AccessWrapper correspondingKillSwitch;
  1078. private boolean lastState;
  1079. public AccessWrapper(HolonObject hObject) {
  1080. type = AccessType.KillSwitch;
  1081. this.hObject = hObject;
  1082. intialStatesOfElementForKilllSwitch = new ArrayList<Boolean>();
  1083. hObject.elementsStream().forEach(hE -> {
  1084. intialStatesOfElementForKilllSwitch.add(hE.active);
  1085. });
  1086. }
  1087. public AccessWrapper(HolonSwitch hSwitch) {
  1088. type = AccessType.Switch;
  1089. this.hSwitch = hSwitch;
  1090. }
  1091. public AccessWrapper(HolonElement hElement, AccessWrapper correspondingKillSwitch) {
  1092. type = AccessType.HolonElement;
  1093. this.hElement = hElement;
  1094. this.correspondingKillSwitch = correspondingKillSwitch;
  1095. }
  1096. public AccessWrapper(Flexibility flex, AccessWrapper correspondingKillSwitch) {
  1097. type = AccessType.Flexibility;
  1098. this.flex = flex;
  1099. this.correspondingKillSwitch = correspondingKillSwitch;
  1100. }
  1101. public void setState(boolean state) {
  1102. lastState = state;
  1103. switch (type) {
  1104. case HolonElement:
  1105. if (!algoUseKillSwitch || (algoUseKillSwitch
  1106. && !correspondingKillSwitch.getLastState())) {
  1107. hElement.active = state;
  1108. }
  1109. break;
  1110. case Switch:
  1111. hSwitch.setMode(SwitchMode.Manual);
  1112. hSwitch.setManualState(state ? SwitchState.Closed : SwitchState.Open);
  1113. break;
  1114. case Flexibility:
  1115. if (state && (!algoUseKillSwitch || (algoUseKillSwitch
  1116. && !correspondingKillSwitch.getLastState()))) {
  1117. flex.order();
  1118. }
  1119. break;
  1120. case KillSwitch:
  1121. if (state) {
  1122. hObject.elementsStream().forEach(hE -> {
  1123. hE.active = false;
  1124. });
  1125. } else {
  1126. List<HolonElement> eleList = hObject.elementsStream().toList();
  1127. for (int i = 0; i < eleList.size(); i++) {
  1128. eleList.get(i).active = intialStatesOfElementForKilllSwitch.get(i);
  1129. }
  1130. }
  1131. break;
  1132. default:
  1133. break;
  1134. }
  1135. }
  1136. public boolean getLastState() {
  1137. return lastState;
  1138. }
  1139. public String typeString() {
  1140. switch (type) {
  1141. case HolonElement:
  1142. return "HolonElement";
  1143. case Switch:
  1144. return "Switch";
  1145. case Flexibility:
  1146. return "Flexibility";
  1147. case KillSwitch:
  1148. return "KillSwitch";
  1149. default:
  1150. return "unknown";
  1151. }
  1152. }
  1153. public String toString() {
  1154. return "[" + typeString() + "]";
  1155. }
  1156. }
  1157. private class Handle<T> {
  1158. public T object;
  1159. Handle(T object) {
  1160. this.object = object;
  1161. }
  1162. public String toString() {
  1163. return object.toString();
  1164. }
  1165. }
  1166. public class Individual {
  1167. public double fitness;
  1168. public List<Boolean> position;
  1169. public Individual() {
  1170. }
  1171. ;
  1172. /**
  1173. * Copy Constructor
  1174. */
  1175. public Individual(Individual c) {
  1176. position = c.position.stream().collect(Collectors.toList());
  1177. fitness = c.fitness;
  1178. }
  1179. String positionToString() {
  1180. return position.stream().map(bool -> (bool ? "1" : "0")).collect(Collectors.joining());
  1181. }
  1182. }
  1183. protected class ParameterStepping<T> {
  1184. boolean useThisParameter = false;
  1185. String paramaterName;
  1186. int stepps;
  1187. T stepSize;
  1188. T startValue;
  1189. Consumer<T> setter;
  1190. Supplier<T> getter;
  1191. BiFunction<Integer, T, T> multyply;
  1192. BiFunction<T, T, T> add;
  1193. private int count = 0;
  1194. ParameterStepping(Consumer<T> setter, Supplier<T> getter, BiFunction<T, T, T> add,
  1195. BiFunction<Integer, T, T> multyply, T stepSize, int stepps) {
  1196. this.setter = setter;
  1197. this.getter = getter;
  1198. this.multyply = multyply;
  1199. this.add = add;
  1200. this.stepSize = stepSize;
  1201. this.stepps = stepps;
  1202. }
  1203. void init() {
  1204. startValue = getter.get();
  1205. }
  1206. boolean canUpdate() {
  1207. return count < stepps;
  1208. }
  1209. void update() {
  1210. if (canUpdate()) {
  1211. setter.accept(add.apply(startValue, multyply.apply(count + 1, stepSize)));
  1212. count++;
  1213. }
  1214. }
  1215. void reset() {
  1216. setter.accept(startValue);
  1217. count = 0;
  1218. }
  1219. }
  1220. }