public void Run() { Render("flowGraph", true); // add reversed edges reversedEdgeAugmentor.AddReversedEdges(); // render with reversed edges Render("flowGraphWithReversedEdges", true); // create max flow algorithm this.maxFlow = new PushRelabelMaximumFlowAlgorithm( this.graph, this.capacities, this.reversedEdgeAugmentor.ReversedEdges ); // compute max flow double f = this.maxFlow.Compute(s, t); Console.WriteLine("Maximum flow: {0}", f); // clean up reversedEdgeAugmentor.RemoveReversedEdges(); // render without reversed edges Render("flowWithOutReversedEdges", true); }
private void Initialize() { this.reverser = new ReversedEdgeAugmentorAlgorithm(this.VisitedGraph); this.reverser.ReversedEdgeAdded += new EdgeEventHandler(reverser_ReversedEdgeAdded); this.maxFlowF1 = new PushRelabelMaximumFlowAlgorithm( this.VisitedGraph, this.capacities, this.reverser.ReversedEdges); }
public MinimumFlowAlgorithm(BidirectionalGraph visitedGraph, EdgeDoubleDictionary capacities) { this.reverser = null; this.balancer = null; this.maxFlowF1 = null; this.maxFlowf2 = null; if (visitedGraph == null) { throw new ArgumentNullException("visitedGraph"); } if (capacities == null) { throw new ArgumentNullException("capacities"); } this.visitedGraph = visitedGraph; this.capacities = capacities; this.Initialize(); }
public MinimumFlowAlgorithm(BidirectionalGraph visitedGraph) { this.reverser = null; this.balancer = null; this.maxFlowF1 = null; this.maxFlowf2 = null; if (visitedGraph == null) { throw new ArgumentNullException("visitedGraph"); } if (this.capacities == null) { throw new ArgumentNullException("capacities"); } this.visitedGraph = visitedGraph; this.capacities = new EdgeDoubleDictionary(); VertexEdgesEnumerator enumerator = this.visitedGraph.Edges.GetEnumerator(); while (enumerator.MoveNext()) { IEdge edge = enumerator.get_Current(); this.capacities.Add(edge, double.MaxValue); } this.Initialize(); }
private bool IsOptimal(MaximumFlowAlgorithm maxFlow) { // check if mincut is saturated... FilteredVertexListGraph residualGraph = new FilteredVertexListGraph( maxFlow.VisitedGraph, new ReversedResidualEdgePredicate(maxFlow.ResidualCapacities, maxFlow.ReversedEdges) ); BreadthFirstSearchAlgorithm bfs = new BreadthFirstSearchAlgorithm(residualGraph); VertexIntDictionary distances = new VertexIntDictionary(); DistanceRecorderVisitor vis = new DistanceRecorderVisitor(distances); bfs.RegisterDistanceRecorderHandlers(vis); bfs.Compute(sink); return distances[source] >= maxFlow.VisitedGraph.VerticesCount; }
private bool IsFlow(MaximumFlowAlgorithm maxFlow) { // check edge flow values foreach (IVertex u in maxFlow.VisitedGraph.Vertices) { foreach (IEdge a in maxFlow.VisitedGraph.OutEdges(u)) { if (maxFlow.Capacities[a] > 0) if ((maxFlow.ResidualCapacities[a] + maxFlow.ResidualCapacities[maxFlow.ReversedEdges[a]] != maxFlow.Capacities[a]) || (maxFlow.ResidualCapacities[a] < 0) || (maxFlow.ResidualCapacities[maxFlow.ReversedEdges[a]] < 0)) return false; } } // check conservation VertexDoubleDictionary inFlows = new VertexDoubleDictionary(); VertexDoubleDictionary outFlows = new VertexDoubleDictionary(); foreach (IVertex u in maxFlow.VisitedGraph.Vertices) { inFlows[u] = 0; outFlows[u] = 0; } foreach (IVertex u in maxFlow.VisitedGraph.Vertices) { foreach (IEdge e in maxFlow.VisitedGraph.OutEdges(u)) { if (maxFlow.Capacities[e] > 0) { double flow = maxFlow.Capacities[e] - maxFlow.ResidualCapacities[e]; inFlows[e.Target] += flow; outFlows[e.Source] += flow; } } } foreach (IVertex u in maxFlow.VisitedGraph.Vertices) { if (u != source && u != sink) if (inFlows[u] != outFlows[u]) return false; } return true; }
public void SimpleGraph(MaximumFlowAlgorithm maxFlow) { double flow = maxFlow.Compute(source, sink); Assert.AreEqual(23, flow, double.Epsilon); Assert.IsTrue(IsFlow(maxFlow)); Assert.IsTrue(IsOptimal(maxFlow)); }