package GKA.Graph; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; public abstract class FlowBase { protected GKAGraph graph; protected Matrix<String, Double> maxFlows; protected Matrix<String, Double> currentFlows; protected long runTime = 0; protected int hops = 0; public FlowBase() { super(); } public int getHops(){ return hops; } public long getRunTime(){ return runTime; } protected void init(GKAGraph graph) { this.graph = graph; Set<String> vertexes = graph.getjGraph().vertexSet(); this.currentFlows = new Matrix<>(vertexes, vertexes); this.maxFlows = generateMaxFlows(); } private Matrix<String, Double> generateMaxFlows() { Set<String> vertexes = graph.getjGraph().vertexSet(); Matrix<String, Double> flows = new Matrix<>(vertexes, vertexes); for(String row: vertexes){ for(String column: vertexes){ double flow = 0.0; for(GKAEdge edge: getAccessibleEdgesBetween(row, column)){ flow += edge.getWeight(); } flows.put(row, column, flow); } } return flows; } private Set<GKAEdge> getAccessibleEdgesBetween(String source, String target) { Set<GKAEdge> edges = new HashSet<>(graph.getjGraph().getAllEdges(source, target)); Set<GKAEdge> notGoable = new HashSet<>(); for (GKAEdge edge : edges) { if(!isEdgeAccessible(edge, source)){ notGoable.add(edge); } } edges.removeAll(notGoable); return edges; } private boolean isEdgeAccessible(GKAEdge edge, String source) { if(edge.getSource().equals(source)){ return true; }else if(!graph.isDirected() && edge.getTarget().equals(source)){ return true; }else{ return false; } } protected void clearFlows() { for(String row: currentFlows.getRows()){ for(String column: currentFlows.getColumns()){ currentFlows.put(row, column, 0.0); } } } protected Set<String> forwardVertexesofSources(String source) { Set<String> vertexes = new HashSet<>(); for (String vertex: maxFlows.getColumns()){ hops++; if (currentFlows.get(source, vertex) < maxFlows.get(source, vertex)){ vertexes.add(vertex); } } return vertexes; } protected Set<String> reverseVertexesofSources(String source) { Set<String> vertexes = new HashSet<>(); for (String vertex: maxFlows.getColumns()){ hops++; if (currentFlows.get(vertex, source) > 0.0){ vertexes.add(vertex); } } return vertexes; } protected double getPossibleFlowBetween(String source, String sink) { return maxFlows.get(source, sink) - currentFlows.get(source, sink); } public double maxFlow(String source, String sink){ clearFlows(); hops = 0; long start = System.nanoTime(); if(source.equals(sink)){ return Double.POSITIVE_INFINITY; } Set<String> forwardVertexes = forwardVertexesofSources(source); if(forwardVertexes.isEmpty()){ runTime = System.nanoTime() - start; return 0.0; } else{ double maxFlow = 0.0; double returnedFlow = 0.0; do{ returnedFlow = maxFlow_(new ArrayList<>(), source, sink, Double.POSITIVE_INFINITY); maxFlow += returnedFlow; }while(returnedFlow != 0.0); runTime = System.nanoTime() - start; return maxFlow; } } abstract protected double maxFlow_(ArrayList<String> alreadyReached, String source, String sink, double maxFlow); }