Browse Source

Adds Randomization to GreedySinglePass

TomTroppmann 2 years ago
parent
commit
ddf5b3dcf2

+ 115 - 19
src/algorithm/binary/GreedySinglePass.java

@@ -1,16 +1,111 @@
 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 api.AlgorithmFrameworkFlex.Individual;
+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{
+public class GreedySinglePass extends AlgorithmFrameworkFlex {
 
 	private int problemSize = 0;
 	private boolean moreInformation = true;
+
+	/**
+	 * Method to get the current Position alias a ListOf Booleans for aktive
+	 * settings on the Objects on the Canvas. Also initialize the Access Hashmap to
+	 * swap faster positions.
+	 * 
+	 * @param model
+	 * @return
+	 */
+	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();
@@ -21,39 +116,40 @@ public class GreedySinglePass extends AlgorithmFrameworkFlex{
 		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);
-		for(int index = 0; index < problemSize; index++)
-		{
+		List<Integer> radomizedForEachLayerIndexList = generateRandomLayerIndexList();
+		for (Integer index : radomizedForEachLayerIndexList) {
 			boolean actualValue = start.position.get(index);
 			start.position.set(index, !actualValue);
 			double fitness = evaluatePosition(start.position);
-			if(fitness < bestFound.fitness) {
-				bestFound = new Individual(start);	
+			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) {
+
+			if (bestFound.fitness < best.fitness) {
 				best = bestFound;
 			}
-			
-			
-			if(cancel) return null;
-			println("Fitness: " + fitness + "FlippedIndex = " + index + "(" + problemSize + ")");
+
+			if (cancel)
+				return null;
+			println("Fitness: " + fitness + "\tFlippedIndex = " + index + "(" + problemSize + ")" + kicked);
 		}
-		
-		
+
 		return best;
 	}
 
-	
-	
 	protected void println(String value) {
-		if(moreInformation)console.println(value);
+		if (moreInformation)
+			console.println(value);
 	}
-	
+
 	@Override
 	protected int getProgressBarMaxCount() {
 		return (problemSize * (problemSize + 1)) / 2;

+ 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);

+ 13 - 8
src/api/AlgorithmFrameworkFlex.java

@@ -15,7 +15,6 @@ 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;
@@ -77,12 +76,18 @@ 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;
-	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;
@@ -771,7 +776,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 	 * @param positionToInit
 	 * @param timeStep
 	 */
-	private void rollOutNodes(Stream<AbstractCanvasObject> nodesExceptGroupNodes, Stream<GroupNode> groupNodes,
+	protected void rollOutNodes(Stream<AbstractCanvasObject> nodesExceptGroupNodes, Stream<GroupNode> groupNodes,
 			Queue<GroupNode> queue, List<Boolean> positionToInit, int timeStep) {
 		nodesExceptGroupNodes.forEach(aCps -> {
 			if (aCps instanceof HolonObject) {
@@ -818,7 +823,7 @@ public abstract class AlgorithmFrameworkFlex implements AddOn {
 		queue.addAll(groupNodes.collect(Collectors.toList()));
 	}
 
-	private void rollOutQueue(Queue<GroupNode> queue, List<Boolean> positionToInit, int timeStep) {
+	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,
@@ -1155,7 +1160,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;
 

+ 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;
+	}
+}