فهرست منبع

Merge branch 'Greedy' into GreedyLogs

Conflicts:
	src/api/AlgorithmFrameworkFlex.java
TomTroppmann 2 سال پیش
والد
کامیت
4b6e2ed1f5

+ 98 - 0
src/algorithm/binary/GreedyAlgorithm.java

@@ -0,0 +1,98 @@
+package algorithm.binary;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import api.AlgorithmFrameworkFlex;
+import utility.StringFormat;
+
+public class GreedyAlgorithm extends AlgorithmFrameworkFlex{
+
+	private int problemSize = 0;
+	private boolean moreInformation = false;
+	
+	
+	public GreedyAlgorithm() {
+		super();
+		addBooleanParameter("More Information", moreInformation, booleanValue -> moreInformation = booleanValue);
+	}
+	
+	
+	
+	
+	@Override
+	protected Individual executeAlgo() {
+		Individual best = new Individual();
+		best.position = extractPositionAndAccess();
+		println("Bit-Array_length: " + best.position.size());
+		best.fitness = evaluatePosition(best.position);
+		List<Double> runList = new ArrayList<Double>();
+		runList.add(best.fitness);
+		println("Start with: " + StringFormat.doubleFixedPlaces(2, best.fitness));
+		problemSize = best.position.size();
+		
+		
+		List<Integer> indexList = new ArrayList<Integer>();
+		for(int index = 0; index < problemSize; index++)
+		{
+			indexList.add(index);
+		}
+		
+		
+		Individual bestAfterRound = new Individual(best);
+		for(int round = 0; round < problemSize; round++)
+		{
+			Individual startInThisRound = new Individual(bestAfterRound);
+			Individual bestInThisRound = new Individual(); 
+			int indexToRemove = -1;
+			bestInThisRound.fitness = Float.MAX_VALUE;
+			for(Integer i : indexList) {
+				boolean actualValue = startInThisRound.position.get(i);
+				startInThisRound.position.set(i, !actualValue);
+				double fitness = evaluatePosition(startInThisRound.position);
+				if(fitness < bestInThisRound.fitness) {
+					bestInThisRound = new Individual(startInThisRound);	
+					bestInThisRound.fitness = fitness;
+					indexToRemove = i;
+					
+				}
+				startInThisRound.position.set(i, actualValue);
+			}
+			if(cancel) return null;
+			bestAfterRound = bestInThisRound;
+			println("Fitness: " + bestInThisRound.fitness + "FlippedIndex = " + indexToRemove + "(" +indexList.size() + ")");
+			if(bestAfterRound.fitness < best.fitness) {
+				best = bestAfterRound;
+			}
+			runList.add(best.fitness);
+			indexList.remove(Integer.valueOf(indexToRemove));
+		}
+		this.runList = runList;
+		console.println("Fitness: " + best.fitness);
+		return best;
+	}
+
+	
+	
+	protected void println(String value) {
+		if(moreInformation)console.println(value);
+	}
+	
+	@Override
+	protected int getProgressBarMaxCount() {
+		List<Boolean> best = extractPositionAndAccess();
+		problemSize = best.size();
+		return ((problemSize * (problemSize + 1)) / 2) * rounds;
+	}
+
+	
+	@Override
+	protected String algoInformationToPrint() {
+		return "NoParameter";
+	}
+
+	@Override
+	protected String plottFileName() {
+		return "plottGreedy.txt";
+	}
+}

+ 172 - 0
src/algorithm/binary/GreedySinglePass.java

@@ -0,0 +1,172 @@
+package algorithm.binary;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import api.AlgorithmFrameworkFlex;
+import classes.AbstractCanvasObject;
+import classes.Flexibility;
+import classes.GroupNode;
+import classes.HolonElement;
+import classes.HolonObject;
+import classes.HolonSwitch;
+import ui.model.Model;
+import utility.StringFormat;
+import utility.Tuple;
+
+public class GreedySinglePass extends AlgorithmFrameworkFlex {
+
+	private int problemSize = 0;
+	private boolean moreInformation = false;
+
+	
+	
+	public GreedySinglePass() {
+		super();
+		addBooleanParameter("More Information", moreInformation, booleanValue -> moreInformation = booleanValue);
+	}
+	
+
+	protected List<Integer> generateRandomLayerIndexList() {
+		Model model = control.getModel();
+		List<AbstractCanvasObject> nodes = (dGroupNode != null) ? dGroupNode.getModel().getNodes()
+				: model.getObjectsOnCanvas();
+		List<Tuple<AbstractCanvasObject, Integer>> extractedObjects = new ArrayList<>();
+		rollOut(nodes.stream(), extractedObjects, 0);
+		// Group With Layer
+		Map<Integer, List<AbstractCanvasObject>> sortetObjects = extractedObjects.stream().collect(
+				Collectors.groupingBy(Tuple::getSecond, Collectors.mapping(Tuple::getFirst, Collectors.toList())));
+		
+		AtomicInteger count = new AtomicInteger(0);
+		List<Integer> indexList = new ArrayList<>();
+		//Generate Access and shuffle layer
+		sortetObjects.entrySet().stream()
+			//ReverseOrder
+			.sorted((layer0, layer1) -> -Integer.compare(layer0.getKey(), layer1.getKey()))
+			//radomizeIndexes
+			.forEach(entry -> {
+				List<Integer> indexesInLayer = entry.getValue().stream().map(node -> count.getAndIncrement()).collect(Collectors.toList());
+				//Randomize Layer
+				Collections.shuffle(indexesInLayer);
+				indexList.addAll(indexesInLayer);
+				
+		});
+		//System.out.println(indexList.stream().map(Object::toString).collect(Collectors.joining(", ")));
+		return indexList;
+	}
+
+	
+
+	protected void rollOut(Stream<AbstractCanvasObject> nodes, List<Tuple<AbstractCanvasObject, Integer>> objects,
+			int layer) {
+
+		nodes.forEach(node -> {
+			if (node instanceof HolonObject) {
+				HolonObject hObject = (HolonObject) node;
+				if (this.algoUseKillSwitch) {
+					objects.add(new Tuple<>(node, layer));
+				}
+				if (this.algoUseElements) {
+					for (@SuppressWarnings("unused") HolonElement hE : hObject.getElements()) {
+						objects.add(new Tuple<>(node, layer));
+					}
+				}
+				if (this.algoUseFlexes) {
+					for (HolonElement hE : hObject.getElements()) {
+						for(Flexibility flex : hE.flexList) {
+							switch(control.getSimManager().getActualFlexManager().getFlexWrapperFromFlexibility(flex).getState()) {
+							case IN_USE:
+							case ON_COOLDOWN:
+								objects.add(new Tuple<>(node, layer));
+								break;
+							case OFFERED:
+								objects.add(new Tuple<>(node, layer));
+								break;
+							case NOT_OFFERED:
+							case UNAVAILABLE:
+							default:
+								break;
+							}
+							
+						}
+					}
+				}
+			} else if (node instanceof HolonSwitch && algoUseSwitches) {
+				objects.add(new Tuple<>(node, layer));
+			}else if (node instanceof GroupNode ) {
+				GroupNode groupNode = (GroupNode) node;
+				rollOut(groupNode.getNodes().stream(), objects, layer +1);
+			}
+		});
+	}
+
+
+	@Override
+	protected Individual executeAlgo() {
+		Individual best = new Individual();
+		best.position = extractPositionAndAccess();
+		println("Bit-Array_length: " + best.position.size());
+		best.fitness = evaluatePosition(best.position);
+		List<Double> runList = new ArrayList<Double>();
+		runList.add(best.fitness);
+		println("Start with: " + StringFormat.doubleFixedPlaces(2, best.fitness));
+		problemSize = best.position.size();
+
+		Individual bestFound = new Individual(best);
+		bestFound.fitness = Float.MAX_VALUE;
+		Individual start = new Individual(best);
+		List<Integer> radomizedForEachLayerIndexList = generateRandomLayerIndexList();
+		
+		for (Integer index : radomizedForEachLayerIndexList) {
+			boolean actualValue = start.position.get(index);
+			start.position.set(index, !actualValue);
+			double fitness = evaluatePosition(start.position);
+			boolean kicked = fitness < bestFound.fitness;
+			if (kicked) {
+				bestFound = new Individual(start);
+				bestFound.fitness = fitness;
+				
+			} else {
+				start.position.set(index, actualValue);
+			}
+
+			if (bestFound.fitness < best.fitness) {
+				best = bestFound;
+			}
+			runList.add(bestFound.fitness);
+			if (cancel)
+				return null;
+			println("Fitness: " + fitness + "\tFlippedIndex = " + index + "(" + problemSize + ")" + kicked);
+		}
+		console.println("Fitness: " + bestFound.fitness);
+		this.runList = runList;
+		return best;
+	}
+
+	protected void println(String value) {
+		if (moreInformation)
+			console.println(value);
+	}
+
+	@Override
+	protected int getProgressBarMaxCount() {
+		List<Boolean> best = extractPositionAndAccess();
+		problemSize = best.size();
+		return problemSize * rounds;
+	}
+	
+	@Override
+	protected String algoInformationToPrint() {
+		return "NoParameter";
+	}
+
+	@Override
+	protected String plottFileName() {
+		return "plottGreedyRandom.txt";
+	}
+}

+ 1 - 1
src/algorithm/objectiveFunction/ObjectiveFunctionByCarlos.java

@@ -46,7 +46,7 @@ public class ObjectiveFunctionByCarlos {
 	 * <br>
 	 *  {@link ObjectiveFunctionByCarlos#squash}
 	 */
-	static double squash_subtract = 1.0f / (1.f + (float) Math.exp(5.0));
+	static double squash_subtract = 100.0f / (1.f + (float) Math.exp(5.0));
 	static double range_for_kappa_f_unre = range(kappa_f_unre);
 	static double range_for_kappa_f_cool = range(kappa_f_cool);
 	static double range_for_kappa_f_dur = range(kappa_f_dur);

+ 1 - 2
src/algorithm/objectiveFunction/SwitchObjectiveFunction.java

@@ -8,7 +8,7 @@ public class SwitchObjectiveFunction {
 	static double w_eb = .5, w_state = .5;
 	static double k_eb = 1050000.f, k_state = 10000;
 	
-	static double squash_subtract = 1.0f / (1.f + (float) Math.exp(5.0));
+	static double squash_subtract = 100.0f / (1.f + (float) Math.exp(5.0));
 	
 	
 	
@@ -21,7 +21,6 @@ public class SwitchObjectiveFunction {
 			
 			//weigt
 			double w_network = net.getAmountOfElements()/elementCountInNetwork;
-			
 			//f_eb
 			double netEnergyDifference = 0;
 			netEnergyDifference += net.getConsumerList().stream().map(con -> con.getEnergySelfSupplied() - con.getEnergyFromConsumingElemnets()).reduce(0.f, Float::sum);

+ 78 - 45
src/api/AlgorithmFrameworkFlex.java

@@ -15,14 +15,16 @@ import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.DoubleSummaryStatistics;
-import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Queue;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
@@ -74,13 +76,19 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 	private JPanel borderPanel = new JPanel();
 
 	// Settings groupNode
-	private DecoratedGroupNode dGroupNode = null;
+
+	protected DecoratedGroupNode dGroupNode = null;
 
 	// access
-	private ArrayList<AccessWrapper> access;
-	private HashMap<HolonObject, AccessWrapper> accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
-	LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
-	boolean algoUseElements = false, algoUseSwitches = true, algoUseFlexes = true, algoUseKillSwitch = true;
+	protected ArrayList<AccessWrapper> access;
+	protected LinkedList<List<Boolean>> resetChain = new LinkedList<List<Boolean>>();
+	protected boolean algoUseElements = false;
+
+	protected boolean algoUseSwitches = true;
+
+	protected boolean algoUseFlexes = true;
+
+	protected boolean algoUseKillSwitch = true;
 
 	// time
 	private long startTime;
@@ -747,68 +755,86 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 	 */
 	protected List<Boolean> extractPositionAndAccess() {
 		Model model = control.getModel();
-		this.accessKillSwitch = new HashMap<HolonObject, AccessWrapper>();
 		access = new ArrayList<AccessWrapper>();
 		List<Boolean> initialState = new ArrayList<Boolean>();
-		rollOutNodes((dGroupNode != null) ? dGroupNode.getModel().getNodes() : model.getObjectsOnCanvas(), initialState,
-				model.getCurIteration());
-		resetChain.add(initialState);
-		if (algoUseFlexes) {
-			for (FlexWrapper flex : control.getSimManager().getActualFlexManager()
-					.getAllFlexWrapperWithState(FlexState.OFFERED)) {
-				// flex.getFlex().getElement().parentObject;
-				AccessWrapper killSwitchAccess = this.algoUseKillSwitch
-						? this.accessKillSwitch.get(flex.getFlex().getElement().parentObject)
-						: null;
-				;
-				access.add(new AccessWrapper(flex.getFlex(), killSwitchAccess));
-				initialState.add(false);
-			}
-			for (FlexWrapper flex : control.getSimManager().getActualFlexManager()
-					.getAllFlexWrapperWithState(FlexState.IN_USE)) {
-				AccessWrapper killSwitchAccess = this.algoUseKillSwitch
-						? this.accessKillSwitch.get(flex.getFlex().getElement().parentObject)
-						: null;
-				access.add(new AccessWrapper(flex.getFlex(), killSwitchAccess));
-				initialState.add(true);
-			}
+		List<AbstractCanvasObject> nodes = (dGroupNode != null) ? dGroupNode.getModel().getNodes()
+				: model.getObjectsOnCanvas();
+		Map<Boolean, List<AbstractCanvasObject>> map = nodes.stream()
+				.collect(Collectors.partitioningBy(aCps -> aCps instanceof GroupNode));
+		Queue<GroupNode> groupNodeQueue = new LinkedList<GroupNode>();
+		rollOutNodes(map.get(false).stream(), map.get(true).stream().map(aCps -> (GroupNode) aCps), groupNodeQueue,
+				initialState, model.getCurIteration());
+		while (!groupNodeQueue.isEmpty()) {
+			rollOutQueue(groupNodeQueue, initialState, model.getCurIteration());
 		}
-		// console.println(access.stream().map(Object::toString).collect(Collectors.joining(",
-		// ")));
+		resetChain.add(initialState);
 		return initialState;
 	}
 
 	/**
+<<<<<<< HEAD
 	 * Method to extract the Informations recursively out of the Model.
+=======
+	 * Method to extract the Informations per Layer out of the Model.
+>>>>>>> refs/heads/Greedy
 	 * 
 	 * @param nodes
 	 * @param positionToInit
 	 * @param timeStep
 	 */
-	private void rollOutNodes(List<AbstractCanvasObject> nodes, List<Boolean> positionToInit, int timeStep) {
-		for (AbstractCanvasObject aCps : nodes) {
+
+	protected void rollOutNodes(Stream<AbstractCanvasObject> nodesExceptGroupNodes, Stream<GroupNode> groupNodes,
+			Queue<GroupNode> queue, List<Boolean> positionToInit, int timeStep) {
+		nodesExceptGroupNodes.forEach(aCps -> {
+
 			if (aCps instanceof HolonObject) {
 				HolonObject hObject = (HolonObject) aCps;
 				AccessWrapper killSwitchAccess = new AccessWrapper(hObject);
 				if (this.algoUseKillSwitch) {
-					positionToInit.add(false);
-					access.add(killSwitchAccess);
-					accessKillSwitch.put(hObject, killSwitchAccess);
+
+					positionToInit.add(0, false);
+					access.add(0, killSwitchAccess);
+
 				}
 				if (this.algoUseElements) {
 					for (HolonElement hE : hObject.getElements()) {
-						positionToInit.add(hE.isActive());
-						access.add(new AccessWrapper(hE, killSwitchAccess));
+
+						positionToInit.add(0, hE.isActive());
+						access.add(0, new AccessWrapper(hE, killSwitchAccess));
+
 					}
 				}
+
+				if (this.algoUseFlexes) {
+					for (HolonElement hE : hObject.getElements()) {
+						for(Flexibility flex : hE.flexList) {
+							switch(control.getSimManager().getActualFlexManager().getFlexWrapperFromFlexibility(flex).getState()) {
+							case IN_USE:
+							case ON_COOLDOWN:
+								positionToInit.add(0, true);
+								access.add(0, new AccessWrapper(flex, killSwitchAccess));
+								break;
+							case OFFERED:
+								positionToInit.add(0, false);
+								access.add(0, new AccessWrapper(flex, killSwitchAccess));
+								break;
+							case NOT_OFFERED:
+							case UNAVAILABLE:
+							default:
+								break;
+							}
+							
+						}
+					}
+				}
+
 			} else if (aCps instanceof HolonSwitch && algoUseSwitches) {
 				HolonSwitch sw = (HolonSwitch) aCps;
-				positionToInit.add(sw.getState(timeStep));
-				access.add(new AccessWrapper(sw));
-			} else if (aCps instanceof GroupNode) {
-				rollOutNodes(((GroupNode) aCps).getNodes(), positionToInit, timeStep);
+				positionToInit.add(0, sw.getState(timeStep));
+				access.add(0, new AccessWrapper(sw));
 			}
-		}
+		});
+		queue.addAll(groupNodes.collect(Collectors.toList()));
 	}
 
 	private void printAddtionalHolonInformation() {
@@ -858,6 +884,12 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 			count++;
 		}
 	}
+	protected void rollOutQueue(Queue<GroupNode> queue, List<Boolean> positionToInit, int timeStep) {
+		Map<Boolean, List<AbstractCanvasObject>> map = queue.remove().getNodes().stream()
+				.collect(Collectors.partitioningBy(aCps -> aCps instanceof GroupNode));
+		rollOutNodes(map.get(false).stream(), map.get(true).stream().map(aCps -> (GroupNode) aCps), queue,
+				positionToInit, timeStep);
+	}
 
 	private RunValues getRunValuesFromActualState() {
 		RunValues val = new RunValues();
@@ -1004,6 +1036,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 			count = 0;
 			isActive = true;
 			progressBar.setValue(0);
+			
 			progressBar.setMaximum(getProgressBarMaxCount());
 		}
 
@@ -1189,7 +1222,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 	 * A Wrapper Class for Access HolonElement and HolonSwitch in one Element and
 	 * not have to split the List.
 	 */
-	private class AccessWrapper {
+	public class AccessWrapper {
 		private AccessType type;
 		private List<Boolean> intialStatesOfElementForKilllSwitch;
 
@@ -1271,7 +1304,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 			case HolonElement:
 				return "HolonElement";
 			case Switch:
-				return "Switch";
+				return "Switch" + hSwitch.getId();
 			case Flexibility:
 				return "Flexibility";
 			case KillSwitch:

+ 25 - 0
src/utility/Tuple.java

@@ -0,0 +1,25 @@
+package utility;
+/**
+ * A simple Tuple implementation with 2 elements. 
+ * @author Tom
+ *
+ * @param <T1> First element Type
+ * @param <T2> Second element Type
+ */
+public class Tuple<T1, T2> {
+	private T1 first;
+	private T2 second;
+
+	public Tuple(T1 first, T2 second) {
+		this.first = first;
+		this.second = second;
+	}
+
+	public T1 getFirst() {
+		return first;
+	}
+
+	public T2 getSecond() {
+		return second;
+	}
+}