|
@@ -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);
|
|
|
+
|
|
|
+ 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<>();
|
|
|
+
|
|
|
+ sortetObjects.entrySet().stream()
|
|
|
+
|
|
|
+ .sorted((layer0, layer1) -> -Integer.compare(layer0.getKey(), layer1.getKey()))
|
|
|
+
|
|
|
+ .forEach(entry -> {
|
|
|
+ List<Integer> indexesInLayer = entry.getValue().stream().map(node -> count.getAndIncrement()).collect(Collectors.toList());
|
|
|
+
|
|
|
+ Collections.shuffle(indexesInLayer);
|
|
|
+ indexList.addAll(indexesInLayer);
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ 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;
|