AlgorithmFrameworkFlex.java 46 KB

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