package GKA.Graph; import java.lang.annotation.Target; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.ListIterator; import java.util.Queue; public class EdmondKarp extends FlowBase{ public EdmondKarp(GKAGraph graph){ init(graph); } // protected double maxFlow_(ArrayList<String> alreadyReached, String source, String sink, double maxFlow){ // HashMap<String, String> parentMap = new HashMap<>(); // Queue<String> queue = new LinkedList<>(); // queue.add(source); // while(queue.size() > 0){ // String aktuellerVertex = queue.poll(); // alreadyReached.add(aktuellerVertex); // for(String nextVertex: forwardVertexesofSources(aktuellerVertex)){ // if((getPossibleFlowBetween(aktuellerVertex, nextVertex) > 0) // && !alreadyReached.contains(nextVertex)){ // parentMap.put(nextVertex, aktuellerVertex); // maxFlow = Double.min(maxFlow, // getPossibleFlowBetween(aktuellerVertex, nextVertex)); // if(nextVertex != sink){ // queue.offer(nextVertex); // } // else{ // while(parentMap.get(nextVertex) != null){ // currentFlows.put(parentMap.get(nextVertex) , nextVertex, // currentFlows.get(parentMap.get(nextVertex) , nextVertex) + maxFlow); // currentFlows.put(nextVertex, parentMap.get(nextVertex) , // currentFlows.get(nextVertex, parentMap.get(nextVertex) ) - maxFlow); // nextVertex = parentMap.get(nextVertex); // } // return maxFlow; // } // } // } // } // return 0.0; // } public double maxFlow(String source, String sink) { if(source.equals(sink)){ return Double.POSITIVE_INFINITY; } HashMap<String, String> parentMap = new HashMap<>(); long start = System.nanoTime(); hops = 0; Matrix<String, Double> capacityMatrix = maxFlows; Matrix<String, Double> flowMatrix = currentFlows; clearFlows(); while (true) { ArrayList<String> reachedVertexes = new ArrayList<>(); //Vorgaengerliste reachedVertexes.add(source); ArrayList<Double> pathCapacity = new ArrayList<>(); pathCapacity.add(Double.POSITIVE_INFINITY);//Pfad Kapazitaeten // BFS queue Queue<String> Q = new LinkedList<String>();//Queue mit Knoten Q.add(source); LOOP: while (!Q.isEmpty()) { String currentNode = Q.remove(); for (String nextNode: forwardVertexesofSources(currentNode)) { hops++; // Es existiert eine Kapazitaet groeßer 0, Pfad moeglich // nextNode noch nicht besucht if ((capacityMatrix.get(currentNode, nextNode) - flowMatrix.get(currentNode, nextNode)) > 0 && !reachedVertexes.contains(nextNode)) { reachedVertexes.add(nextNode); parentMap.put(nextNode, currentNode); pathCapacity.add( Math.min( pathCapacity.get(reachedVertexes.indexOf(currentNode)), capacityMatrix.get(currentNode, nextNode) - flowMatrix.get(currentNode, nextNode)) ); if (!nextNode.equals(sink)) Q.add(nextNode); else { // Backtrack search, and write flow while(parentMap.get(nextNode) != null) { hops++; flowMatrix.put(parentMap.get(nextNode), nextNode, flowMatrix.get(parentMap.get(nextNode), nextNode) + pathCapacity.get(pathCapacity.size()-1)); flowMatrix.put( nextNode, parentMap.get(nextNode), flowMatrix.get(nextNode, parentMap.get(nextNode)) - pathCapacity.get(pathCapacity.size() - 1)); nextNode = parentMap.get(nextNode); } break LOOP; } } } } if (!reachedVertexes.contains(sink)) { // kein Weg zur Senke gefunden Double sum = 0.0; for (String row : flowMatrix.getRows()) { hops++; sum += flowMatrix.get(source,row); } runTime = System.nanoTime() - start; return sum; } } } @Override protected double maxFlow_(ArrayList<String> alreadyReached, String source, String sink, double maxFlow) { // TODO Auto-generated method stub return 0; } }