RandomOfferdFlexibility.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. package addOns;
  2. import java.awt.BorderLayout;
  3. import java.awt.ComponentOrientation;
  4. import java.awt.Dimension;
  5. import java.awt.FlowLayout;
  6. import java.awt.GridBagConstraints;
  7. import java.awt.GridBagLayout;
  8. import java.math.RoundingMode;
  9. import java.text.NumberFormat;
  10. import java.util.ArrayList;
  11. import java.util.Collections;
  12. import java.util.Hashtable;
  13. import java.util.List;
  14. import java.util.Locale;
  15. import java.util.Random;
  16. import java.util.stream.Collectors;
  17. import javax.swing.BorderFactory;
  18. import javax.swing.JButton;
  19. import javax.swing.JCheckBox;
  20. import javax.swing.JFormattedTextField;
  21. import javax.swing.JFrame;
  22. import javax.swing.JLabel;
  23. import javax.swing.JPanel;
  24. import javax.swing.JSlider;
  25. import javax.swing.text.NumberFormatter;
  26. import com.google.gson.internal.Streams;
  27. import api.AddOn;
  28. import classes.AbstractCanvasObject;
  29. import classes.GroupNode;
  30. import classes.Flexibility;
  31. import classes.HolonElement;
  32. import classes.HolonElement.Priority;
  33. import classes.HolonObject;
  34. import ui.controller.Control;
  35. /**
  36. * A short algorithm to distribute the Priorities for the whole Canvas.
  37. * @author tom
  38. *
  39. */
  40. public class RandomOfferdFlexibility implements AddOn {
  41. private Control control;
  42. private JPanel content = new JPanel();
  43. private class PriorityDependeces{
  44. public JCheckBox checkbox;
  45. public JSlider slider = new JSlider(JSlider.HORIZONTAL,0, 100, 50);
  46. public JLabel positive = new JLabel("0 \u2192 0(0)");
  47. public JLabel negative = new JLabel("0 \u2192 0(0)");
  48. public FlexOffered offer = new FlexOffered();
  49. public List<Flexibility> flexList = new ArrayList<Flexibility>();
  50. public PriorityDependeces(String name){
  51. checkbox = new JCheckBox(name, true);
  52. }
  53. public void update() {
  54. List<Flexibility> positiveList = flexList.stream().filter(flex -> flex.isPositive()).collect(Collectors.toList());
  55. offer.positive.maximumOffered = positiveList.size();
  56. offer.positive.actualOffered = (int)positiveList.stream().filter(flex -> (flex.offered)).count();
  57. List<Flexibility> negativeList = flexList.stream().filter(flex -> flex.isNegative()).collect(Collectors.toList());
  58. offer.negative.maximumOffered = negativeList.size();
  59. offer.negative.actualOffered = (int)negativeList.stream().filter(flex -> (flex.offered)).count();
  60. offer.updateActualProportion();
  61. setTarget(offer.proportion);
  62. }
  63. public void setTarget(double proprotion) {
  64. offer.updateTarget(proprotion);
  65. //Update slider
  66. slider.setValue((int)(offer.proportion * 100.0));
  67. //Update Label
  68. positive.setText(offer.positive.actualOffered + " \u2192 " + offer.positive.targetOffered + "(" + offer.positive.maximumOffered + ")");
  69. negative.setText(offer.negative.actualOffered + " \u2192 " + offer.negative.targetOffered + "(" + offer.negative.maximumOffered + ")");
  70. }
  71. public void updateCanvasToTargetAmounts() {
  72. List<Flexibility> positiveList = flexList.stream().filter(flex -> flex.isPositive()).collect(Collectors.toList());
  73. Collections.shuffle(positiveList, new Random());
  74. for(int i = 0; i < positiveList.size(); i++){
  75. positiveList.get(i).offered = (i < offer.positive.targetOffered);
  76. }
  77. List<Flexibility> negativeList = flexList.stream().filter(flex -> flex.isNegative()).collect(Collectors.toList());
  78. Collections.shuffle(negativeList, new Random());
  79. for(int i = 0; i < negativeList.size(); i++){
  80. negativeList.get(i).offered = (i < offer.negative.targetOffered);
  81. }
  82. if(control != null) {
  83. control.calculateStateAndVisualForCurrentTimeStep();
  84. }
  85. }
  86. }
  87. private class FlexOffered{
  88. public double proportion = 0.5;
  89. public FlexTypeOffered positive = new FlexTypeOffered();
  90. public FlexTypeOffered negative = new FlexTypeOffered();
  91. public void updateTarget(double proportion) {
  92. //Clamp between 0 and 1
  93. proportion = Math.min(1, Math.max(0, proportion));
  94. if(1 == proportion) {
  95. negative.targetOffered = 0;
  96. positive.targetOffered = positive.maximumOffered;
  97. }else if(0 == proportion) {
  98. positive.targetOffered = 0;
  99. negative.targetOffered = negative.maximumOffered;
  100. }else {
  101. //x * proportion = positive.maximumOffered
  102. int maximumAmountBothA = (int)((double)positive.maximumOffered /proportion);
  103. int amountOtherSide = maximumAmountBothA - positive.maximumOffered;
  104. if(amountOtherSide <= negative.maximumOffered) {
  105. negative.targetOffered = amountOtherSide;
  106. positive.targetOffered = positive.maximumOffered;
  107. }else {
  108. int maximumAmountBothB = (int)((double)negative.maximumOffered / (1.0 -proportion));
  109. int amountOtherSideB = maximumAmountBothB - negative.maximumOffered;
  110. positive.targetOffered = amountOtherSideB;
  111. negative.targetOffered = negative.maximumOffered;
  112. }
  113. }
  114. }
  115. public void updateActualProportion() {
  116. if(positive.actualOffered + negative.actualOffered == 0) {
  117. proportion = 0.5;
  118. }else {
  119. proportion = (double)positive.actualOffered / (double)(positive.actualOffered + negative.actualOffered);
  120. }
  121. }
  122. public double getActualProportion() {
  123. if(positive.actualOffered + negative.actualOffered == 0) {
  124. return 0.5;
  125. }
  126. return (double)positive.actualOffered / (double)(positive.actualOffered + negative.actualOffered);
  127. }
  128. }
  129. private class FlexTypeOffered{
  130. int actualOffered = 0;
  131. int maximumOffered = 0;
  132. int targetOffered = 0;
  133. }
  134. PriorityDependeces low = new PriorityDependeces("low");
  135. PriorityDependeces medium = new PriorityDependeces("medium");
  136. PriorityDependeces high = new PriorityDependeces("high");
  137. PriorityDependeces essential = new PriorityDependeces("essential");
  138. public static void main(String[] args)
  139. {
  140. JFrame newFrame = new JFrame("exampleWindow");
  141. RandomOfferdFlexibility instance = new RandomOfferdFlexibility();
  142. newFrame.setContentPane(instance.getPanel());
  143. newFrame.pack();
  144. newFrame.setVisible(true);
  145. newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  146. }
  147. public RandomOfferdFlexibility(){
  148. low.offer.positive.maximumOffered = low.offer.positive.actualOffered = 1000;
  149. low.offer.negative.maximumOffered = low.offer.negative.actualOffered = 2000;
  150. double distribution = 0.8;
  151. low.offer.updateTarget(distribution);
  152. System.out.println("distribution:" + distribution + " Positive:" + low.offer.positive.targetOffered
  153. + " Negative:" + low.offer.negative.targetOffered);
  154. System.out.println("actualDistribution:" + low.offer.getActualProportion());
  155. content.setLayout(new BorderLayout());
  156. content.add(createFlexPanel(), BorderLayout.CENTER);
  157. JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
  158. JButton buttonReload = new JButton("Reload");
  159. buttonReload.setToolTipText("Press to relaod all canvas changes.");
  160. buttonReload.addActionListener(actionEvent -> update());
  161. buttonPanel.add(buttonReload);
  162. JButton buttonRun = new JButton("Run");
  163. buttonRun.setToolTipText("Changes the actual offered flex to the random target amount of selected prioritys.");
  164. buttonRun.addActionListener(actionEvent -> run());
  165. buttonPanel.add(buttonRun);
  166. content.add(buttonPanel, BorderLayout.PAGE_END);
  167. //content.setPreferredSize(new Dimension(300,500));
  168. }
  169. private JPanel createFlexPanel() {
  170. JPanel flexPanel = new JPanel();
  171. flexPanel.setBorder(BorderFactory.createTitledBorder("Flexibility"));
  172. flexPanel.setLayout(new GridBagLayout());
  173. GridBagConstraints c = new GridBagConstraints();
  174. c.fill = GridBagConstraints.HORIZONTAL;
  175. c.gridx = 0;
  176. c.gridy = 0;
  177. c.ipadx = 10;
  178. //c.ipady = 100;
  179. //Label
  180. flexPanel.add(new JLabel("Priority:"), c);
  181. c.gridx++;
  182. flexPanel.add(new JLabel("Target:"), c);
  183. c.gridx++;
  184. flexPanel.add(new JLabel("Positive#(Available):"), c);
  185. c.gridx++;
  186. flexPanel.add(new JLabel("Negative#(Available):"), c);
  187. c.gridx = 0;
  188. c.gridy = 1;
  189. flexPanel.add(low.checkbox, c);c.gridx++;
  190. c.weightx = 1;
  191. flexPanel.add(createTargetSetterPanel(this.low), c);c.gridx++;
  192. c.weightx = 0;
  193. flexPanel.add(this.low.positive, c);c.gridx++;
  194. flexPanel.add(this.low.negative, c);
  195. c.gridx = 0;
  196. c.gridy = 2;
  197. flexPanel.add(medium.checkbox, c);c.gridx++;
  198. flexPanel.add(createTargetSetterPanel(this.medium), c);c.gridx++;
  199. flexPanel.add(this.medium.positive, c);c.gridx++;
  200. flexPanel.add(this.medium.negative, c);
  201. c.gridx = 0;
  202. c.gridy = 3;
  203. flexPanel.add(high.checkbox, c);c.gridx++;
  204. flexPanel.add(createTargetSetterPanel(this.high), c);c.gridx++;
  205. flexPanel.add(this.high.positive, c);c.gridx++;
  206. flexPanel.add(this.high.negative, c);
  207. c.gridx = 0;
  208. c.gridy = 4;
  209. flexPanel.add(essential.checkbox, c);c.gridx++;
  210. flexPanel.add(createTargetSetterPanel(this.essential), c);c.gridx++;
  211. flexPanel.add(this.essential.positive, c);c.gridx++;
  212. flexPanel.add(this.essential.negative, c);
  213. return flexPanel;
  214. }
  215. private JPanel createTargetSetterPanel(PriorityDependeces priorityD) {
  216. JPanel panel = new JPanel();
  217. panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
  218. panel.setLayout(new GridBagLayout());
  219. GridBagConstraints c = new GridBagConstraints();
  220. c.fill = GridBagConstraints.HORIZONTAL;
  221. c.gridx = 0;
  222. c.gridy = 0;
  223. c.weightx = 0;
  224. c.anchor = GridBagConstraints.NORTH;
  225. panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
  226. NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
  227. doubleFormat.setMinimumFractionDigits(0);
  228. doubleFormat.setMaximumFractionDigits(2);
  229. doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
  230. NumberFormatter doubleFormatter = new NumberFormatter(doubleFormat);
  231. doubleFormatter.setMinimum(0.0);
  232. doubleFormatter.setMaximum(1.0);
  233. //doubleFormatter.setCommitsOnValidEdit(true);
  234. JFormattedTextField change = new JFormattedTextField(doubleFormatter);
  235. change.addActionListener(ChangeEvent -> priorityD.slider.setValue((int)(Double.parseDouble(change.getValue().toString()) * 100.0)));
  236. change.setText("0.1");
  237. change.setPreferredSize(new Dimension(40,20));
  238. panel.add(change, c);
  239. c.fill = GridBagConstraints.HORIZONTAL;
  240. c.gridx = 1;
  241. c.weightx = 1;
  242. priorityD.slider.setMajorTickSpacing(50);
  243. priorityD.slider.setMinorTickSpacing(5);
  244. priorityD.slider.setPaintTicks(true);
  245. Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
  246. labelTable.put( Integer.valueOf( 0 ), new JLabel("Positiv") );
  247. labelTable.put( Integer.valueOf( 100 ), new JLabel("Negativ") );
  248. priorityD.slider.addChangeListener(changeEvent -> {
  249. priorityD.offer.proportion = (double)priorityD.slider.getValue()/100.0;
  250. priorityD.slider.setToolTipText("" + priorityD.offer.proportion);
  251. change.setText("" +priorityD.offer.proportion);
  252. priorityD.setTarget(priorityD.offer.proportion);
  253. });
  254. priorityD.slider.setLabelTable( labelTable );
  255. priorityD.slider.setPaintLabels(true);
  256. panel.add(priorityD.slider, c);
  257. return panel;
  258. }
  259. private void run() {
  260. //control.getModel().getObjectsOnCanvas().stream().filter(aCps -> aCps instanceof HolonObject)
  261. if(control == null) {
  262. System.out.println("Nothing to do");
  263. return;
  264. }
  265. if(low.checkbox.isSelected()) low.updateCanvasToTargetAmounts();
  266. if(medium.checkbox.isSelected()) medium.updateCanvasToTargetAmounts();
  267. if(high.checkbox.isSelected()) high.updateCanvasToTargetAmounts();
  268. if(essential.checkbox.isSelected()) essential.updateCanvasToTargetAmounts();
  269. }
  270. private List<HolonObject> createListOfHolonObjects(List<AbstractCanvasObject> objectsOnCanvas) {
  271. List<HolonObject> list = new ArrayList<HolonObject>();
  272. for(AbstractCanvasObject aCps : objectsOnCanvas) {
  273. if(aCps instanceof HolonObject) list.add((HolonObject) aCps);
  274. else if(aCps instanceof GroupNode)list.addAll(createListOfHolonObjects(((GroupNode)aCps).getNodes()));
  275. }
  276. return list;
  277. }
  278. public void update() {
  279. if(control == null) {
  280. return;
  281. }
  282. List<HolonElement> elementList = createListOfHolonObjects(control.getModel().getObjectsOnCanvas()).stream().flatMap(hObject -> hObject.getElements().stream()).collect(Collectors.toList());
  283. control.calculateStateAndVisualForCurrentTimeStep();
  284. control.updateCanvas();
  285. List<Flexibility> flexList = control.getSimManager().getActualFlexManager().getAllFlexWrapper().stream().filter(flexwrapper -> flexwrapper.getFlex().offered).map(flex -> flex.getFlex()).collect(Collectors.toList());
  286. low.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Low && flex.fulfillsConstrains()).collect(Collectors.toList());
  287. medium.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Medium && flex.fulfillsConstrains()).collect(Collectors.toList());
  288. high.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.High && flex.fulfillsConstrains()).collect(Collectors.toList());
  289. essential.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Essential && flex.fulfillsConstrains()).collect(Collectors.toList());
  290. low.update();
  291. medium.update();
  292. high.update();
  293. essential.update();
  294. }
  295. @Override
  296. public JPanel getPanel() {
  297. return content;
  298. }
  299. @Override
  300. public void setController(Control control) {
  301. this.control = control;
  302. update();
  303. }
  304. }