package holeg.algorithm.objective_function; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; import java.util.logging.Logger; import holeg.model.AbstractCanvasObject; import holeg.model.HolonSwitch; import holeg.ui.model.Model; import java.util.Set; //TODO(Tom2022-01-13) Fix GraphMetrics public class GraphMetrics { private static final Logger log = Logger.getLogger(GraphMetrics.class.getName()); public static class Vertex{ public int id = 0; public Vertex(int id){ this.id = id; } public String toString() { return "" + id; } } private static class Edge{ public int idA, idB; public double weight; public Edge(int idA, int idB, double weight){ this.idA = idA; this.idB = idB; this.weight = weight; } } public static class Graph{ Vertex[] V; Edge[] E; /**Only the Sources/Trains for disjoint Path no Switch or Node**/ Vertex[] S; public String toString() { String vList = "V" + Arrays.toString(V); String sList = "S" + Arrays.toString(S); return vList + ", " + sList; } } /** * Convert a DecoratedNetwork to a Graph * @param net * @return a equivalent Graph to the DecoratedNetwork */ public static Graph convertDecoratedNetworkToGraph(Model model) { Graph G = new Graph(); HashMap objectToId = new HashMap<>(); List sourcesList = new ArrayList(); int count = 0; // for(Consumer con: net.getConsumerList()) { // objectToId.put(con.getModel(), count); // sourcesList.add(count); // count++; // } // for(Consumer con: net.getConsumerSelfSuppliedList()) { // objectToId.put(con.getModel(), count); // sourcesList.add(count); // count++; // } // for(Passiv pas: net.getPassivNoEnergyList()) { // objectToId.put(pas.getModel(), count); // sourcesList.add(count); // count++; // } // for(Supplier sup: net.getSupplierList()) { // objectToId.put(sup.getModel(), count); // sourcesList.add(count); // count++; // } // //Generate EdgeList // List edgeList = new ArrayList(); // for(holeg.model.Edge cable : net.getDecoratedCableList()){ // // AbstractCanvasObject objectA = cable.getA(); // AbstractCanvasObject objectB = cable.getB(); // if(objectA == null) { // log.warning("Edge: " + cable + "objectA == null"); // continue; // } // if(objectB == null) { // log.warning("Edge: " + cable + "objectB == null"); // continue; // } // // //SpecialCase for open switches // if(objectA instanceof HolonSwitch sw && !sw.getManualState()) { // continue; // } // if(objectB instanceof HolonSwitch sw && !sw.getManualState()) { // continue; // } // // int idA = -1; // if(objectToId.containsKey(objectA)) { // idA = objectToId.get(objectA); // }else { // idA = count; // objectToId.put(objectA, count++); // } // int idB = -1; // if(objectToId.containsKey(objectB)) { // idB = objectToId.get(objectB); // }else { // idB = count; // objectToId.put(objectB, count++); // } // double length = cable.getLength(); // edgeList.add(new Edge(idA, idB, length)); // } // //Generate EdgeArray // G.E = new Edge[edgeList.size()]; // for(int i=0;i entry : objectToId.entrySet()) { // G.V[entryCount] = new Vertex(entry.getValue()); // entryCount++; // } // //Generate Sources Array // int sourceCount = 0; // G.S = new Vertex[sourcesList.size()]; // for(int source : sourcesList) { // G.S[sourceCount] = new Vertex(source); // sourceCount++; // } return G; } // Example Test public static void main(String[] args){ Graph G = new Graph(); G.V = new Vertex[4]; for(int i=0;i visitedNotes = new HashSet(); //Queue to check which node to search next LinkedList queue = new LinkedList(); //Map to traverse the path back when found a path HashMap noteBeforeMap = new HashMap(); //Add starting Point queue.add(s); //Visit all neighbours of the next point in queue while(!queue.isEmpty()) { int id = queue.pollFirst(); visitedNotes.add(id); //For all neighbors add to queue for(int i = 0; i < L[id].length; i++) { //Check if edge exist and not visited before if(L[id][i] != 0 && !visitedNotes.contains(i)) { queue.add(i); noteBeforeMap.putIfAbsent(i, id); //check if train is found if(i == t) { //update connectionMatrix l and remove the found path int actualID = t; while(actualID != s) { int nextID = noteBeforeMap.get(actualID); //remove edge L[nextID][actualID] = 0; L[actualID][nextID] = 0; actualID = nextID; } return true; } } } } //if last queue element is searched but t is not reachable return false; } /** * Makes a deep Copy of a Integer Matrix * @param l_input * @return */ private static int[][] makeCopyOfMatrix(int[][] matrix) { int[][] copyMatrix = new int[matrix.length][matrix[0].length]; for(int i = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { copyMatrix[i][j] = matrix[i][j]; } } return copyMatrix; } /** * Stoer Wagner Minimal Cut Algo * Source from * * https://github.com/hunglvosu/algorithm/blob/master/algorithm/src/Stoer-Wagner.c
* in C formatted written in java * @param V Vertex Array * @param E Edge Array * @return */ static int minimumCut(Vertex[] V, Edge[] E) { int[][] W = generateDisjointWeightMatrix(V, E); boolean[] Del = new boolean[V.length]; int n = V.length; // the number of veritces int m = E.length; return StoerWagner(n, m, W, Del); } static int StoerWagner(int n, int m, int[][] W, boolean[] Del){ int C = Integer.MAX_VALUE; for(int V = n; V > 1; V--){ int cutValue = minCutPhase(V, W, Del, n, m); C = (C < cutValue ? C: cutValue); } return C; } static int minCutPhase(int V, int[][] W, boolean[] Del, int n, int m){ int i = 0, j = 0; int[] s = new int[2]; if(V == 2) { for( i = 0; i < n; i++){ if(Del[i] == false){ s[j] = i; j++; } } return W[s[0]][s[1]]; } int[] L = new int[n]; boolean[] T = new boolean[n]; i = 1; // the number of vertices in the tree T j = 0; int v,u; while( i <= V){ v = maxStickiness(T,L, Del, n); T[v] = true; for(u = 0; u < n; u++){ if(W[v][u] != 0 && Del[u] == false && T[u] == false){ L[u] = L[u] + W[u][v]; } } if( i >= V-1){ s[j] = v; j++; } i++; } merge(s[0], s[1], n, W, Del); return L[s[1]]; } static int maxStickiness(boolean[] T, int[] L, boolean[] Del, int n){ int i = 0; int v = 0; int max = 0; for(i = 0; i < n; i++){ if(Del[i] == false && T[i] == false && max < L[i]){ v = i; max = L[i]; } } return v; } static void merge(int s, int t, int n, int[][] W, boolean[] Del){ int v = 0; for(v = 0; v < n; v++){ if(Del[v] == false && v != s && v!= t){ W[s][v] = W[s][v] + W[v][t]; W[v][s] = W[s][v]; } } Del[t] = true; } static double[][] basicAllPairsShortestPath(Vertex[] V, Edge[] E){ double[][] L = generateWeightMatrix(V, E); double[][] D = generateDistanceMatrix(V); boolean[] flag = generateFlagList(V); for(int i=0;i visitedNotes = new LinkedList(); LinkedList minPriorityQueue = new LinkedList(); minPriorityQueue.add(source); while(!minPriorityQueue.isEmpty()) { minPriorityQueue.sort((a,b) -> Double.compare(D[source][a], D[source][b])); int target = minPriorityQueue.pop(); if(flag[source] == true) { for(int outgoingID = 0; outgoingID < L.length; outgoingID++) { if(D[source][target] + L[target][outgoingID] < D[source][outgoingID]) { D[source][outgoingID] = D[source][target] + L[target][outgoingID]; } } }else { for(int outgoingID = 0; outgoingID < L.length; outgoingID++) { if(L[target][outgoingID] == Double.POSITIVE_INFINITY) continue; if(D[source][target] + L[target][outgoingID] < D[source][outgoingID]) { D[source][outgoingID] = D[source][target] + L[target][outgoingID]; if(!visitedNotes.contains(outgoingID)) { minPriorityQueue.add(outgoingID); } } } } visitedNotes.add(target); } flag[source] = true; } static double[][] generateWeightMatrix(Vertex[] V, Edge[] E){ double[][] L = new double[V.length][V.length]; for(int i = 0; i < E.length; i++) { try { L[E[i].idA][E[i].idB] = E[i].weight; L[E[i].idB][E[i].idA] = E[i].weight; }catch(java.lang.NullPointerException e) { log.info("E[i].idA:" + E[i].idA + " E[i].idB:" + E[i].idB + " E[i].weight:" + E[i].weight); } } for(int i=0;i