Browse Source

Randomizer for Offering Flexibilities

Tom Troppmann 3 years ago
parent
commit
203e35690a
2 changed files with 255 additions and 93 deletions
  1. 249 91
      src/addOns/RandomOfferdFlexibility.java
  2. 6 2
      src/classes/Flexibility.java

+ 249 - 91
src/addOns/RandomOfferdFlexibility.java

@@ -1,22 +1,32 @@
 package addOns;
 
 import java.awt.BorderLayout;
-import java.awt.Component;
+import java.awt.ComponentOrientation;
 import java.awt.Dimension;
-import java.awt.GridLayout;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.math.RoundingMode;
+import java.text.NumberFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Locale;
+import java.util.Random;
 import java.util.stream.Collectors;
 
 import javax.swing.BorderFactory;
-import javax.swing.BoxLayout;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
+import javax.swing.JFormattedTextField;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JSlider;
+import javax.swing.text.NumberFormatter;
+
+import com.google.gson.internal.Streams;
 
 import api.AddOn;
 import classes.AbstractCanvasObject;
@@ -25,7 +35,6 @@ import classes.Flexibility;
 import classes.HolonElement;
 import classes.HolonElement.Priority;
 import classes.HolonObject;
-import classes.HolonSwitch;
 import ui.controller.Control;
 
 /**
@@ -44,28 +53,117 @@ public class RandomOfferdFlexibility implements AddOn {
 	private Control  control;
 	
 	private JPanel content = new JPanel();
-	private JSlider activeSlider = new JSlider(JSlider.HORIZONTAL,0, 100, 50);
 
 
 
+	private class PriorityDependeces{
+		public JCheckBox checkbox;
+		public JSlider slider = new JSlider(JSlider.HORIZONTAL,0, 100, 50);
+		
+		public JLabel positive = new JLabel("0 \u2192 0(0)");
+		public JLabel negative = new JLabel("0 \u2192 0(0)");
+		public FlexOffered offer = new FlexOffered();
+		public List<Flexibility> flexList = new ArrayList<Flexibility>();
+		public PriorityDependeces(String name){
+			checkbox = new JCheckBox(name, true);
+		}
+		public void update() {
+			List<Flexibility> positiveList = flexList.stream().filter(flex -> flex.isPositive()).collect(Collectors.toList());
+			offer.positive.maximumOffered = positiveList.size();
+			offer.positive.actualOffered = (int)positiveList.stream().filter(flex -> (flex.offered)).count();
+			List<Flexibility> negativeList = flexList.stream().filter(flex -> flex.isNegative()).collect(Collectors.toList());
+			offer.negative.maximumOffered = negativeList.size();
+			offer.negative.actualOffered = (int)negativeList.stream().filter(flex -> (flex.offered)).count();
+			offer.updateActualProportion();
+			setTarget(offer.proportion);
+		}
+		public void setTarget(double proprotion) {
+			offer.updateTarget(proprotion);
+			//Update slider
+			slider.setValue((int)(offer.proportion * 100.0));
+			//Update Label
+			positive.setText(offer.positive.actualOffered + " \u2192 " + offer.positive.targetOffered + "(" + offer.positive.maximumOffered + ")");
+			negative.setText(offer.negative.actualOffered + " \u2192 " + offer.negative.targetOffered + "(" + offer.negative.maximumOffered + ")");
+
+		}
+		public void updateCanvasToTargetAmounts() {
+			List<Flexibility> positiveList = flexList.stream().filter(flex -> flex.isPositive()).collect(Collectors.toList());
+			Collections.shuffle(positiveList, new Random());
+			for(int i = 0; i < positiveList.size(); i++){
+				positiveList.get(i).offered = (i < offer.positive.targetOffered);
+			}
+			List<Flexibility> negativeList = flexList.stream().filter(flex -> flex.isNegative()).collect(Collectors.toList());
+			Collections.shuffle(negativeList, new Random());
+			for(int i = 0; i < negativeList.size(); i++){
+				negativeList.get(i).offered = (i < offer.negative.targetOffered);
+			}
+			if(control != null) {
+				control.calculateStateAndVisualForCurrentTimeStep();
+			}
+		}
+	}
+	private class FlexOffered{
+		public double proportion = 0.5;
+		public FlexTypeOffered positive = new FlexTypeOffered();
+		public FlexTypeOffered negative = new FlexTypeOffered();
+		public void updateTarget(double proportion) {
+			//Clamp between 0 and 1
+			proportion = Math.min(1, Math.max(0, proportion));
+			if(1 == proportion) {
+				negative.targetOffered = 0;
+				positive.targetOffered = positive.maximumOffered;
+			}else if(0 == proportion) {
+				positive.targetOffered = 0;
+				negative.targetOffered = negative.maximumOffered;
+			}else {
+				//x * proportion = positive.maximumOffered
+				int maximumAmountBothA = (int)((double)positive.maximumOffered /proportion);
+				int amountOtherSide = maximumAmountBothA - positive.maximumOffered;
+				if(amountOtherSide <= negative.maximumOffered) {
+					negative.targetOffered = amountOtherSide;
+					positive.targetOffered = positive.maximumOffered;
+				}else {
+					int maximumAmountBothB = (int)((double)negative.maximumOffered / (1.0 -proportion));
+					int amountOtherSideB = maximumAmountBothB - negative.maximumOffered;
+					positive.targetOffered = amountOtherSideB;
+					negative.targetOffered = negative.maximumOffered;
+				}
+			}
+		}
+		public void updateActualProportion() {
+			if(positive.actualOffered + negative.actualOffered == 0) {
+				proportion = 0.5;
+			}else {
+				proportion = (double)positive.actualOffered / (double)(positive.actualOffered + negative.actualOffered);
+			}
+		}
+		public double getActualProportion() {
+			if(positive.actualOffered + negative.actualOffered == 0) {
+				return 0.5;
+			}
+			return (double)positive.actualOffered / (double)(positive.actualOffered + negative.actualOffered);
+		}
+	}
+	private class FlexTypeOffered{
+		int actualOffered = 0;
+		int maximumOffered = 0;
+		int targetOffered = 0;
+	}
+	PriorityDependeces low = new PriorityDependeces("low");
+	PriorityDependeces medium = new PriorityDependeces("medium");
+	PriorityDependeces high = new PriorityDependeces("high");
+	PriorityDependeces essential = new PriorityDependeces("essential");
+	
 	
-	private JCheckBox lowCheckbox = new JCheckBox("Low", true);
-	private JCheckBox mediumCheckbox = new JCheckBox("Medium", true);
-	private JCheckBox highCheckbox = new JCheckBox("High", true);
-	private JCheckBox essentialCheckbox = new JCheckBox("Essential", true);
-	private JSlider lowFlexTargetSlider = new JSlider(JSlider.HORIZONTAL,0, 100, 50);
-	private JSlider mediumFlexTargetSlider = new JSlider(JSlider.HORIZONTAL,0, 100, 50);
-	private JSlider highFlexTargetSlider = new JSlider(JSlider.HORIZONTAL,0, 100, 50);
-	private JSlider essentialFlexTargetSlider = new JSlider(JSlider.HORIZONTAL,0, 100, 50);
 
-	private JLabel lowPositiveLabel = new JLabel("0(0)");
-	private JLabel mediumPositiveLabel = new JLabel("0(0)");
-	private JLabel highPositiveLabel = new JLabel("0(0)");
-	private JLabel essentialPositiveLabel = new JLabel("0(0)");
-	private JLabel lowNegativeLabel = new JLabel("0(0)");
-	private JLabel mediumNegativeLabel = new JLabel("0(0)");
-	private JLabel highNegativeLabel = new JLabel("0(0)");
-	private JLabel essentialNegativeLabel = new JLabel("0(0)");
+	
+	
+	
+	
+	
+	
+	
+	
 	public static void main(String[] args)
 	{
 	      JFrame newFrame = new JFrame("exampleWindow");
@@ -79,107 +177,151 @@ public class RandomOfferdFlexibility implements AddOn {
 	
 	
 	public RandomOfferdFlexibility(){
-		content.setLayout(new BorderLayout());
-		content.add(createParameterPanel(), BorderLayout.CENTER);
-		content.add(createFlexPanel(), BorderLayout.EAST);
+		low.offer.positive.maximumOffered = low.offer.positive.actualOffered =  1000;
+		low.offer.negative.maximumOffered = low.offer.negative.actualOffered = 2000;
+		double distribution = 0.8; 
+		low.offer.updateTarget(distribution);
+		System.out.println("distribution:" + distribution + " Positive:" + low.offer.positive.targetOffered
+				+ " Negative:" + low.offer.negative.targetOffered);
+		System.out.println("actualDistribution:" + low.offer.getActualProportion());
 		
+		
+		content.setLayout(new BorderLayout());
+		content.add(createFlexPanel(), BorderLayout.CENTER);
+		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
+
+		JButton buttonReload = new JButton("Reload");
+		buttonReload.setToolTipText("Press to relaod all canvas changes.");
+		buttonReload.addActionListener(actionEvent -> update());
+		buttonPanel.add(buttonReload);
 		JButton buttonRun = new JButton("Run");
+		buttonRun.setToolTipText("Changes the actual offered flex to the random target amount of selected prioritys.");
 		buttonRun.addActionListener(actionEvent -> run());
-		content.add(buttonRun, BorderLayout.PAGE_END);
+		buttonPanel.add(buttonRun);
+		content.add(buttonPanel, BorderLayout.PAGE_END);
 
 		//content.setPreferredSize(new Dimension(300,500));
 	}
 	private JPanel createFlexPanel() {
 		JPanel flexPanel = new JPanel();
 		flexPanel.setBorder(BorderFactory.createTitledBorder("Flexibility"));
-		GridLayout experimentLayout = new GridLayout(0,4);
-		flexPanel.setLayout(experimentLayout);
-		
-		//Label
+		flexPanel.setLayout(new GridBagLayout());
+		GridBagConstraints c = new GridBagConstraints();
 		
-		flexPanel.add(new JLabel("Priority:"));
-		flexPanel.add(new JLabel("Target:"));
-		flexPanel.add(new JLabel("PositiveAmount:"));
-		flexPanel.add(new JLabel("NegativeAmount:"));
+		c.fill = GridBagConstraints.HORIZONTAL;
+		c.gridx = 0;
+		c.gridy = 0;
+		c.ipadx = 10;
+		//c.ipady = 100;
 		
-		flexPanel.add(lowCheckbox);
-		flexPanel.add(initVisualizeSliderFlexibility(this.lowFlexTargetSlider, "PositivNegativ"));
-		flexPanel.add(this.lowPositiveLabel);
-		flexPanel.add(this.lowNegativeLabel);
-		
-		flexPanel.add(mediumCheckbox);
-		flexPanel.add(initVisualizeSliderFlexibility(this.mediumFlexTargetSlider, "PositivNegativ"));
-		flexPanel.add(this.mediumPositiveLabel);
-		flexPanel.add(this.mediumNegativeLabel);
+		//Label
+		flexPanel.add(new JLabel("Priority:"), c);
+		c.gridx++;
+		flexPanel.add(new JLabel("Target:"), c);
+		c.gridx++;
+		flexPanel.add(new JLabel("Positive#(Available):"), c);
+		c.gridx++;
+		flexPanel.add(new JLabel("Negative#(Available):"), c);
+
+		c.gridx = 0;
+		c.gridy = 1;
 		
-		flexPanel.add(highCheckbox);
-		flexPanel.add(initVisualizeSliderFlexibility(this.highFlexTargetSlider, "PositivNegativ"));
-		flexPanel.add(this.highPositiveLabel);
-		flexPanel.add(this.highNegativeLabel);
 		
-		flexPanel.add(essentialCheckbox);
-		flexPanel.add(initVisualizeSliderFlexibility(this.essentialFlexTargetSlider, "PositivNegativ"));
-		flexPanel.add(this.essentialPositiveLabel);
-		flexPanel.add(this.essentialNegativeLabel);
+		flexPanel.add(low.checkbox, c);c.gridx++;
+		c.weightx = 1;
+		flexPanel.add(createTargetSetterPanel(this.low), c);c.gridx++;
+		c.weightx = 0;
+		flexPanel.add(this.low.positive, c);c.gridx++;
+		flexPanel.add(this.low.negative, c);
 		
-		return flexPanel;
-	}
-
-
-
-	private JPanel createParameterPanel() {
-		JPanel centerPanel = new JPanel();
-		JPanel parameterPanel = new JPanel();
-		parameterPanel.setBorder(BorderFactory.createTitledBorder("Priority"));
-		parameterPanel.setLayout(new BoxLayout(parameterPanel, BoxLayout.PAGE_AXIS));
-		createParamaterSlider(parameterPanel);
+		c.gridx = 0;
+		c.gridy = 2;
 		
+		flexPanel.add(medium.checkbox, c);c.gridx++;
+		flexPanel.add(createTargetSetterPanel(this.medium), c);c.gridx++;
+		flexPanel.add(this.medium.positive, c);c.gridx++;
+		flexPanel.add(this.medium.negative, c);
 		
-		centerPanel.add(parameterPanel);
-		return centerPanel;
-	}
-	private void createParamaterSlider(JPanel parameterPanel) {
+		c.gridx = 0;
+		c.gridy = 3;
 		
-
 		
+		flexPanel.add(high.checkbox, c);c.gridx++;
+		flexPanel.add(createTargetSetterPanel(this.high), c);c.gridx++;
+		flexPanel.add(this.high.positive, c);c.gridx++;
+		flexPanel.add(this.high.negative, c);
 		
+		c.gridx = 0;
+		c.gridy = 4;
 		
+		flexPanel.add(essential.checkbox, c);c.gridx++;
+		flexPanel.add(createTargetSetterPanel(this.essential), c);c.gridx++;
+		flexPanel.add(this.essential.positive, c);c.gridx++;
+		flexPanel.add(this.essential.negative, c);
 		
+		return flexPanel;
 	}
 
-	private JSlider initVisualizeSliderFlexibility(JSlider jslider, String name) {
-		jslider.setMajorTickSpacing(50);
-		jslider.setMinorTickSpacing(5);
-		jslider.setPaintTicks(true);
+	private JPanel createTargetSetterPanel(PriorityDependeces priorityD) {
+		JPanel panel = new JPanel();
+		panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
+		panel.setLayout(new GridBagLayout());
+		GridBagConstraints c = new GridBagConstraints();
+		c.fill = GridBagConstraints.HORIZONTAL;
+		c.gridx = 0;
+		c.gridy = 0;
+		c.weightx = 0;
+		c.anchor = GridBagConstraints.NORTH;
+		panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
+		NumberFormat doubleFormat = NumberFormat.getNumberInstance(Locale.US);
+		doubleFormat.setMinimumFractionDigits(0);
+		doubleFormat.setMaximumFractionDigits(2);
+		doubleFormat.setRoundingMode(RoundingMode.HALF_UP);
+		NumberFormatter doubleFormatter = new NumberFormatter(doubleFormat);
+		doubleFormatter.setMinimum(0.0);
+		doubleFormatter.setMaximum(1.0);
+		//doubleFormatter.setCommitsOnValidEdit(true);
+		JFormattedTextField change = new JFormattedTextField(doubleFormatter);
+		change.addActionListener(ChangeEvent -> priorityD.slider.setValue((int)(Double.parseDouble(change.getValue().toString()) * 100.0)));
+		change.setText("0.1");
+		change.setPreferredSize(new Dimension(40,20));
+		panel.add(change, c);
+		c.fill = GridBagConstraints.HORIZONTAL;
+		c.gridx = 1;
+		c.weightx = 1;
+		priorityD.slider.setMajorTickSpacing(50);
+		priorityD.slider.setMinorTickSpacing(5);
+		priorityD.slider.setPaintTicks(true);
 		Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
 		labelTable.put( Integer.valueOf( 0 ), new JLabel("Positiv") );
 		labelTable.put( Integer.valueOf( 100 ), new JLabel("Negativ") );
-		jslider.setLabelTable( labelTable );
-		jslider.setPaintLabels(true);
-		return jslider;
+		priorityD.slider.addChangeListener(changeEvent -> {
+			priorityD.offer.proportion = (double)priorityD.slider.getValue()/100.0;
+			priorityD.slider.setToolTipText("" + priorityD.offer.proportion);
+			change.setText("" +priorityD.offer.proportion);
+			priorityD.setTarget(priorityD.offer.proportion);
+		});
+		priorityD.slider.setLabelTable( labelTable );
+		priorityD.slider.setPaintLabels(true);
+		panel.add(priorityD.slider, c);
+		return panel;
 	}
 	
 	
 	
+	
+	
 	private void run() {
 		//control.getModel().getObjectsOnCanvas().stream().filter(aCps -> aCps instanceof HolonObject)
-		List<HolonElement> elementList = createListOfHolonObjects(control.getModel().getObjectsOnCanvas()).stream().flatMap(hObject -> hObject.getElements().stream()).collect(Collectors.toList());
-		for(HolonElement element : elementList) {
-			element.setActive(Math.random() * 100.0 < activeSlider.getValue());
-			// Generate a random number between 0 and 100
-			
-			
+		
+		if(control == null) {
+			System.out.println("Nothing to do");
+			return;
 		}
-		control.calculateStateAndVisualForCurrentTimeStep();
-		control.updateCanvas();
-		List<Flexibility> flexList = control.getSimManager().getActualFlexManager().getAllFlexWrapper().stream().filter(flexwrapper -> flexwrapper.getFlex().offered).map(flex -> flex.getFlex()).collect(Collectors.toList());
-		long amountOfEssential = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Essential).count();
-		long amountOfHigh = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.High).count();
-		long amountOfMedium = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Medium).count();
-		long amountOfLow = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Low).count();
-		long overall = amountOfEssential + amountOfHigh + amountOfMedium + amountOfLow;
-		System.out.println(" amountOfEssential: " + amountOfEssential  + " amountOfHigh: " + amountOfHigh + " amountOfMedium: " +amountOfMedium + " amountOfLow: " +amountOfLow + " of overall " + overall + "Flexes");
-	
+		if(low.checkbox.isSelected()) low.updateCanvasToTargetAmounts();
+		if(medium.checkbox.isSelected()) medium.updateCanvasToTargetAmounts();
+		if(high.checkbox.isSelected()) high.updateCanvasToTargetAmounts();
+		if(essential.checkbox.isSelected()) essential.updateCanvasToTargetAmounts();
 	}
 	
 	
@@ -193,7 +335,23 @@ public class RandomOfferdFlexibility implements AddOn {
 	}
 	return list;
 	}
-	
+	public void update() {
+		if(control == null) {
+			return;
+		}
+		List<HolonElement> elementList = createListOfHolonObjects(control.getModel().getObjectsOnCanvas()).stream().flatMap(hObject -> hObject.getElements().stream()).collect(Collectors.toList());
+		control.calculateStateAndVisualForCurrentTimeStep();
+		control.updateCanvas();
+		List<Flexibility> flexList = control.getSimManager().getActualFlexManager().getAllFlexWrapper().stream().filter(flexwrapper -> flexwrapper.getFlex().offered).map(flex -> flex.getFlex()).collect(Collectors.toList());
+		low.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Low && flex.fulfillsConstrains()).collect(Collectors.toList());
+		medium.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Medium && flex.fulfillsConstrains()).collect(Collectors.toList());
+		high.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.High && flex.fulfillsConstrains()).collect(Collectors.toList());
+		essential.flexList = flexList.stream().filter(flex -> flex.getElement().getPriority() == Priority.Essential && flex.fulfillsConstrains()).collect(Collectors.toList());
+		low.update();
+		medium.update();
+		high.update();
+		essential.update();
+	}
 	
 	
 	@Override
@@ -203,7 +361,7 @@ public class RandomOfferdFlexibility implements AddOn {
 	@Override
 	public void setController(Control control) {
 		this.control = control;
-		
+		update();
 	}
 
 }

+ 6 - 2
src/classes/Flexibility.java

@@ -92,8 +92,12 @@ public class Flexibility {
 		//System.out.println("Name:" +  element.getEleName() + "   BringtMir:" + (-element.getEnergyPerElement() * element.getAmount()));
 		return (constrainList.stream().map(constrain -> constrain.getName()).anyMatch(name -> name.equals("onConstrain"))?-1.0f:1.0f) * element.getEnergyPerElement() * element.getAmount();
 	}
-	
-	
+	public boolean isPositive() {
+		return bringtmir() >= 0;
+	}
+	public boolean isNegative() {
+		return bringtmir() < 0;
+	}