public void AddReversedEdges_Throws() { var graph = new AdjacencyGraph <int, Edge <int> >(); EdgeFactory <int, Edge <int> > edgeFactory = (source, target) => new Edge <int>(source, target); var algorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph, edgeFactory); Assert.DoesNotThrow(() => algorithm.AddReversedEdges()); Assert.Throws <InvalidOperationException>(() => algorithm.AddReversedEdges()); }
public void Dispose() { var graph = new AdjacencyGraph <int, Edge <int> >(); EdgeFactory <int, Edge <int> > edgeFactory = (source, target) => new Edge <int>(source, target); var algorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph, edgeFactory); CollectionAssert.IsEmpty(algorithm.AugmentedEdges); CollectionAssert.IsEmpty(algorithm.ReversedEdges); ((IDisposable)algorithm).Dispose(); CollectionAssert.IsEmpty(algorithm.AugmentedEdges); CollectionAssert.IsEmpty(algorithm.ReversedEdges); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(2, 3), new Edge <int>(3, 2) }); algorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph, edgeFactory); algorithm.AddReversedEdges(); CollectionAssert.IsNotEmpty(algorithm.AugmentedEdges); CollectionAssert.IsNotEmpty(algorithm.ReversedEdges); ((IDisposable)algorithm).Dispose(); CollectionAssert.IsEmpty(algorithm.AugmentedEdges); CollectionAssert.IsEmpty(algorithm.ReversedEdges); }
public void AddAndRemoveOnEmptyGraph() { this.target = new ReversedEdgeAugmentorAlgorithm(new AdjacencyGraph()); target.AddReversedEdges(); Assert.AreEqual(0, this.target.VisitedGraph.VerticesCount); Assert.AreEqual(0, this.target.VisitedGraph.EdgesCount); }
public void EdmondsKarpMaxFlow_NegativeCapacity_Throws() { const int source = 1; const int sink = 4; var graph = new AdjacencyGraph <int, TaggedEdge <int, double> >(); // TaggedEdge.Tag is the capacity of the edge graph.AddVerticesAndEdgeRange(new[] { new TaggedEdge <int, double>(1, 2, 3), new TaggedEdge <int, double>(1, 4, 4), new TaggedEdge <int, double>(2, 3, -1), new TaggedEdge <int, double>(3, 4, 1) }); EdgeFactory <int, TaggedEdge <int, double> > edgeFactory = (sourceNode, targetNode) => new TaggedEdge <int, double>(sourceNode, targetNode, 0.0); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <int, TaggedEdge <int, double> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <int, TaggedEdge <int, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm); Assert.Throws <NegativeCapacityException>(() => algorithm.Compute(source, sink)); }
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); }
public void AddAndRemoveAndCheckAugmented() { this.target = new ReversedEdgeAugmentorAlgorithm(new AdjacencyGraph()); Assert.IsFalse(target.Augmented); target.AddReversedEdges(); Assert.IsTrue(target.Augmented); target.RemoveReversedEdges(); Assert.IsFalse(target.Augmented); }
public static string Test() { //////////////////////////////////////// // test maximum flow algorith ////////////////////////////////////////// var g = new BidirectionalGraph <string, Edge <string> >(true); string source = "A"; string sink = "G"; //Vertices ////////////// g.AddVertex("A"); g.AddVertex("B"); g.AddVertex("C"); g.AddVertex("D"); g.AddVertex("E"); g.AddVertex("F"); g.AddVertex("G"); //Edge //////////// var edgesList = new List <Edge <string> >(); var ad = new Edge <string>("A", "D"); g.AddEdge(ad); edgeCapacitiesDictionaryTest.Add(ad, 2); var ab = new Edge <string>("A", "B"); g.AddEdge(ab); edgeCapacitiesDictionaryTest.Add(ab, 3); var bc = new Edge <string>("B", "C"); g.AddEdge(bc); edgeCapacitiesDictionaryTest.Add(bc, 3); var ca = new Edge <string>("C", "A"); g.AddEdge(ca); edgeCapacitiesDictionaryTest.Add(ca, 4); var cd = new Edge <string>("C", "D"); g.AddEdge(cd); edgeCapacitiesDictionaryTest.Add(cd, 1); var de = new Edge <string>("D", "E"); g.AddEdge(de); edgeCapacitiesDictionaryTest.Add(de, 7); var df = new Edge <string>("D", "F"); g.AddEdge(df); edgeCapacitiesDictionaryTest.Add(df, 4); var eb = new Edge <string>("E", "B"); g.AddEdge(eb); edgeCapacitiesDictionaryTest.Add(eb, 1); var ce = new Edge <string>("C", "E"); g.AddEdge(ce); edgeCapacitiesDictionaryTest.Add(ce, 2); var eg = new Edge <string>("E", "G"); g.AddEdge(eg); edgeCapacitiesDictionaryTest.Add(eg, 3); var fg = new Edge <string>("F", "G"); g.AddEdge(fg); edgeCapacitiesDictionaryTest.Add(fg, 4); ///////////////////////////////////// // creating the augmentor //////////////////////////////////// var reversedEdgeAugmentor = new ReversedEdgeAugmentorAlgorithm <string, Edge <string> >(g, MyEdgeFactoryTest); reversedEdgeAugmentor.AddReversedEdges(); // (other option) new PushRelabelMaximumFlowAlgorithm MaximumFlowAlgorithm <string, Edge <string> > algo = new EdmondsKarpMaximumFlowAlgorithm <string, Edge <string> >(g, /*e => 2*/ ComputeCapacityTest, reversedEdgeAugmentor.ReversedEdges); algo.Compute(source, sink); //algo.Compute(); StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("MaxFlow: {0}", algo.MaxFlow)); sb.AppendLine("Press <ENTER> to complete"); return(sb.ToString()); }
public static double Get(AdjacencyGraph <string, EquatableTaggedEdge <string, double> > graph, string source, string sink) { // edgeFactory will be used to create the reversed edges to store residual capacities using the ReversedEdgeAugmentorAlgorithm-class. // The edgeFactory assigns a capacity of 0.0 for the new edges because the initial (residual) capacity must be 0.0. EdgeFactory <string, EquatableTaggedEdge <string, double> > edgeFactory = (sourceNode, targetNode) => new EquatableTaggedEdge <string, double>(sourceNode, targetNode, 0.0); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <string, EquatableTaggedEdge <string, double> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <string, EquatableTaggedEdge <string, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm); algorithm.Compute(source, sink); return(algorithm.MaxFlow); }
public void AddAndRemoveOneEdge() { AdjacencyGraph g = new AdjacencyGraph(); IVertex v = g.AddVertex(); IVertex u = g.AddVertex(); IEdge edge = g.AddEdge(u, v); this.target = new ReversedEdgeAugmentorAlgorithm(g); target.AddReversedEdges(); target.RemoveReversedEdges(); Assert.AreEqual(2, this.target.VisitedGraph.VerticesCount); Assert.AreEqual(1, this.target.VisitedGraph.EdgesCount); CollectionAssert.AreCountEqual(0, this.target.AugmentedEdges); Assert.AreEqual(0, this.target.ReversedEdges.Count); }
public void EdmondsKarpMaxFlow_WrongVertices_Throws() { var graph = new AdjacencyGraph <TestVertex, TaggedEdge <TestVertex, double> >(); EdgeFactory <TestVertex, TaggedEdge <TestVertex, double> > edgeFactory = (source, target) => new TaggedEdge <TestVertex, double>(source, target, 0.0); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm); var vertex1 = new TestVertex("1"); var vertex2 = new TestVertex("2"); Assert.Throws <InvalidOperationException>(() => algorithm.Compute()); algorithm = new EdmondsKarpMaximumFlowAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >( graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm) { Source = vertex1 }; Assert.Throws <InvalidOperationException>(() => algorithm.Compute()); algorithm = new EdmondsKarpMaximumFlowAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >( graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm) { Source = vertex1, Sink = vertex2 }; Assert.Throws <VertexNotFoundException>(() => algorithm.Compute()); algorithm = new EdmondsKarpMaximumFlowAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >( graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm) { Source = vertex1, Sink = vertex2 }; graph.AddVertex(vertex1); Assert.Throws <VertexNotFoundException>(() => algorithm.Compute()); }
public void AddReversedEdges <TEdge>(EdgeFactory <int, TEdge> edgeFactory) where TEdge : IEdge <int> { TEdge edge12 = edgeFactory(1, 2); TEdge edge13 = edgeFactory(1, 3); TEdge edge23 = edgeFactory(2, 3); TEdge edge32 = edgeFactory(3, 2); var graph = new AdjacencyGraph <int, TEdge>(); graph.AddVerticesAndEdgeRange(new[] { edge12, edge13, edge23, edge32 }); var algorithm = new ReversedEdgeAugmentorAlgorithm <int, TEdge>(graph, edgeFactory); var reverseEdgesAdded = new List <TEdge>(); algorithm.ReversedEdgeAdded += edge => reverseEdgesAdded.Add(edge); algorithm.AddReversedEdges(); Assert.IsTrue(algorithm.Augmented); CollectionAssert.IsNotEmpty(algorithm.AugmentedEdges); var augmentedEdges = algorithm.AugmentedEdges.ToArray(); Assert.AreEqual(2, augmentedEdges.Length); Assert.AreEqual(2, augmentedEdges[0].Source); Assert.AreEqual(1, augmentedEdges[0].Target); Assert.AreEqual(3, augmentedEdges[1].Source); Assert.AreEqual(1, augmentedEdges[1].Target); CollectionAssert.AreEquivalent( new Dictionary <TEdge, TEdge> { [edge12] = augmentedEdges[0], [augmentedEdges[0]] = edge12, [edge13] = augmentedEdges[1], [augmentedEdges[1]] = edge13, [edge23] = edge32, [edge32] = edge23, }, algorithm.ReversedEdges); CollectionAssert.AreEqual(augmentedEdges, reverseEdgesAdded); }
public void NotReachableSink() { const string source = "A"; const string sink = "G"; var graph = new AdjacencyGraph <string, TaggedEdge <string, double> >(true); graph.AddVertexRange(new[] { "A", "B", "C", "D", "E", "F", "G" }); // TaggedEdge.Tag is the capacity of the edge graph.AddEdgeRange(new[] { new TaggedEdge <string, double>("A", "D", 3), new TaggedEdge <string, double>("A", "B", 3), new TaggedEdge <string, double>("B", "C", 4), new TaggedEdge <string, double>("C", "A", 3), new TaggedEdge <string, double>("C", "D", 1), new TaggedEdge <string, double>("D", "E", 2), new TaggedEdge <string, double>("D", "F", 6), new TaggedEdge <string, double>("E", "B", 1), new TaggedEdge <string, double>("C", "E", 2) }); // edgeFactory will be used to create the reversed edges to store residual capacities using the ReversedEdgeAugmentorAlgorithm-class. // The edgeFactory assigns a capacity of 0.0 for the new edges because the initial (residual) capacity must be 0.0. EdgeFactory <string, TaggedEdge <string, double> > edgeFactory = (sourceNode, targetNode) => new TaggedEdge <string, double>(sourceNode, targetNode, 0.0); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <string, TaggedEdge <string, double> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <string, TaggedEdge <string, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm); algorithm.Compute(source, sink); Assert.AreEqual(source, algorithm.Source); Assert.AreEqual(sink, algorithm.Sink); Assert.AreEqual(graph.VertexCount, algorithm.VerticesColors.Count); foreach (KeyValuePair <string, GraphColor> pair in algorithm.VerticesColors) { Assert.AreEqual( pair.Key == sink ? GraphColor.White : GraphColor.Black, pair.Value); } Assert.AreEqual(0, algorithm.MaxFlow); }
public void EdmondsKarpMaxFlow_Throws() { var graph = new AdjacencyGraph <TestVertex, TaggedEdge <TestVertex, double> >(); EdgeFactory <TestVertex, TaggedEdge <TestVertex, double> > edgeFactory = (source, target) => new TaggedEdge <TestVertex, double>(source, target, 0.0); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <TestVertex, TaggedEdge <TestVertex, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm); var vertex = new TestVertex("1"); // ReSharper disable AssignNullToNotNullAttribute Assert.Throws <ArgumentNullException>(() => algorithm.Compute(null, vertex)); Assert.Throws <ArgumentNullException>(() => algorithm.Compute(vertex, null)); Assert.Throws <ArgumentNullException>(() => algorithm.Compute(null, null)); // ReSharper restore AssignNullToNotNullAttribute }
public void GetVertexColor_Throws() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVertexRange(new[] { 0, 1 }); Func <Edge <int>, double> capacities = edge => 1.0; EdgeFactory <int, Edge <int> > edgeFactory = (source, target) => new Edge <int>(source, target); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph, capacities, edgeFactory, reverseEdgesAlgorithm); algorithm.Compute(0, 1); // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Assert.Throws <VertexNotFoundException>(() => algorithm.GetVertexColor(2)); }
private static double RunMaxFlowAlgorithm <TVertex, TEdge>(IMutableVertexAndEdgeListGraph <TVertex, TEdge> g, EdgeFactory <TVertex, TEdge> edgeFactory, TVertex source, TVertex sink) where TEdge : IEdge <TVertex> { var reversedEdgeAugmentorAlgorithm = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>(g, edgeFactory); reversedEdgeAugmentorAlgorithm.AddReversedEdges(); TryFunc <TVertex, TEdge> flowPredecessors; var flow = AlgorithmExtensions.MaximumFlowEdmondsKarp <TVertex, TEdge>( g, e => 1, source, sink, out flowPredecessors, edgeFactory, reversedEdgeAugmentorAlgorithm ); reversedEdgeAugmentorAlgorithm.RemoveReversedEdges(); return(flow); }
public void AddOneEdge() { AdjacencyGraph g = new AdjacencyGraph(); IVertex v = g.AddVertex(); IVertex u = g.AddVertex(); IEdge edge = g.AddEdge(u, v); this.target = new ReversedEdgeAugmentorAlgorithm(g); target.AddReversedEdges(); Assert.AreEqual(2, this.target.VisitedGraph.VerticesCount); Assert.AreEqual(2, this.target.VisitedGraph.EdgesCount); CollectionAssert.AreCountEqual(1, this.target.AugmentedEdges); VerifyReversedEdges(); IEdge reversedEdge = this.target.ReversedEdges[edge]; Assert.IsNotNull(reversedEdge); Assert.IsTrue(this.target.AugmentedEdges.Contains(reversedEdge)); }
public void GetVertexColor() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdge(new Edge <int>(1, 2)); graph.AddVertex(3); Func <Edge <int>, double> capacities = edge => 1.0; EdgeFactory <int, Edge <int> > edgeFactory = (source, target) => new Edge <int>(source, target); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph, capacities, edgeFactory, reverseEdgesAlgorithm); algorithm.Compute(1, 2); Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(1)); Assert.AreEqual(GraphColor.White, algorithm.GetVertexColor(2)); Assert.AreEqual(GraphColor.White, algorithm.GetVertexColor(3)); }
public static string Main(BidirectionalGraph <Word, Edge <Word> > g) { gr = g; foreach (var item in g.Edges) { //edgeCapacitiesDictionary.Add(item, 0); } var reversedEdgeAugmentor = new ReversedEdgeAugmentorAlgorithm <Word, Edge <Word> >(g, MyEdgeFactory); reversedEdgeAugmentor.AddReversedEdges(); //p.; // (other option) new PushRelabelMaximumFlowAlgorithm MaximumFlowAlgorithm <Word, Edge <Word> > algo = new EdmondsKarpMaximumFlowAlgorithm <Word, Edge <Word> >(g, ComputeCapacity, reversedEdgeAugmentor.ReversedEdges); Dictionary <Edge <Word>, double> d = new Dictionary <Edge <Word>, double>(); foreach (var item in g.Edges) { algo = new EdmondsKarpMaximumFlowAlgorithm <Word, Edge <Word> >(g, ComputeCapacity, reversedEdgeAugmentor.ReversedEdges); double value = algo.Compute(item.Source, item.Target); d.Add(item, value); } //algo.Compute(); //algo.Compute(source, sink); //return algo.MaxFlow; StringBuilder sb = new StringBuilder(); foreach (var item in d) { sb.AppendLine(item.ToString()); } return(sb.ToString()); }
private static double RunMaxFlowAlgorithmAndCheck <TVertex, TEdge>( [NotNull] IMutableVertexAndEdgeListGraph <TVertex, TEdge> graph, [NotNull] EdgeFactory <TVertex, TEdge> edgeFactory, [NotNull] TVertex source, [NotNull] TVertex sink) where TEdge : IEdge <TVertex> { var reversedEdgeAugmentorAlgorithm = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>(graph, edgeFactory); reversedEdgeAugmentorAlgorithm.AddReversedEdges(); double flow = graph.MaximumFlow( edge => 1, source, sink, out _, edgeFactory, reversedEdgeAugmentorAlgorithm); reversedEdgeAugmentorAlgorithm.RemoveReversedEdges(); return(flow); }
public void RemoveReversedEdges() { var edge12 = new Edge <int>(1, 2); var edge13 = new Edge <int>(1, 3); var edge23 = new Edge <int>(2, 3); var edge32 = new Edge <int>(3, 2); var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { edge12, edge13, edge23, edge32 }); var algorithm = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >( graph, (source, target) => new Edge <int>(source, target)); algorithm.AddReversedEdges(); Assert.IsTrue(algorithm.Augmented); CollectionAssert.IsNotEmpty(algorithm.AugmentedEdges); foreach (Edge <int> edge in algorithm.AugmentedEdges) { CollectionAssert.Contains(algorithm.VisitedGraph.Edges, edge); } CollectionAssert.IsNotEmpty(algorithm.ReversedEdges); algorithm.RemoveReversedEdges(); Assert.IsFalse(algorithm.Augmented); CollectionAssert.IsEmpty(algorithm.AugmentedEdges); foreach (Edge <int> edge in algorithm.AugmentedEdges) { CollectionAssert.DoesNotContain(algorithm.VisitedGraph.Edges, edge); } CollectionAssert.IsEmpty(algorithm.ReversedEdges); }
public void Compute(IVertex source, IVertex sink) { // step 1 constructor balancing graph this.balancer = new GraphBalancerAlgorithm( this.VisitedGraph, source, sink, this.capacities ); balancer.Balance(); this.capacities[balancer.BalancingSourceEdge] = 0; this.capacities[balancer.BalancingSinkEdge] = 0; // step 2 find max flow reverser.AddReversedEdges(); maxFlowF1.Compute(source, sink); // step 3 this.capacities[balancer.BalancingSourceEdge] = double.MaxValue; foreach (IEdge edge in balancer.SurplusEdges) { IVertex v = edge.Target; // find edges foreach (IEdge vs in this.VisitedGraph.OutEdges(v)) { if (vs.Target == balancer.BalancingSource) { this.capacities[vs] = 0; } } } // step 4: // reverser.RemoveReversedEdges(); // balancer.UnBalance(); }
public static EdmondsKarpMaximumFlowAlgorithm <T, Edge <T> > CreateAlgorithmAndMaybeDoComputation <T>( [NotNull] ContractScenario <T> scenario) { var graph = new AdjacencyGraph <T, Edge <T> >(); graph.AddVerticesAndEdgeRange(scenario.EdgesInGraph.Select(e => new Edge <T>(e.Source, e.Target))); graph.AddVertexRange(scenario.SingleVerticesInGraph); double Capacities(Edge <T> edge) => 1.0; Edge <T> EdgeFactory(T source, T target) => new Edge <T>(source, target); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <T, Edge <T> >(graph, EdgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <T, Edge <T> >(graph, Capacities, EdgeFactory, reverseEdgesAlgorithm); if (scenario.DoComputation) { algorithm.Compute(scenario.Root, scenario.AccessibleVerticesFromRoot.First()); } return(algorithm); }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge> augmentor = null; ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverser = null; try { if (cancelManager.IsCancelling) { return; } // Augmenting the graph augmentor = new BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge>( this, VisitedGraph, SourceToVertices, VerticesToSink, VertexFactory, EdgeFactory); augmentor.Compute(); if (cancelManager.IsCancelling) { return; } // Adding reverse edges reverser = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>( VisitedGraph, EdgeFactory); reverser.AddReversedEdges(); if (cancelManager.IsCancelling) { return; } // Compute maximum flow var flow = new EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge>( this, VisitedGraph, edge => 1.0, EdgeFactory, reverser); flow.Compute(augmentor.SuperSource, augmentor.SuperSink); if (cancelManager.IsCancelling) { return; } foreach (TEdge edge in VisitedGraph.Edges) { if (Math.Abs(flow.ResidualCapacities[edge]) < float.Epsilon) { if (edge.Source.Equals(augmentor.SuperSource) || edge.Source.Equals(augmentor.SuperSink) || edge.Target.Equals(augmentor.SuperSource) || edge.Target.Equals(augmentor.SuperSink)) { // Skip all edges that connect to SuperSource or SuperSink continue; } _matchedEdges.Add(edge); } } } finally { if (reverser != null && reverser.Augmented) { reverser.RemoveReversedEdges(); } if (augmentor != null && augmentor.Augmented) { augmentor.Rollback(); } } }
protected override void InternalCompute() { var cancelManager = this.Services.CancelManager; this.MatchedEdges.Clear(); BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge> augmentor = null; ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverser = null; try { if (cancelManager.IsCancelling) { return; } //augmenting graph augmentor = new BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge>( this, this.VisitedGraph, this.VertexSetA, this.VertexSetB, this.VertexFactory, this.EdgeFactory); augmentor.Compute(); if (cancelManager.IsCancelling) { return; } //adding reverse edges reverser = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>( this, this.VisitedGraph, this.EdgeFactory ); reverser.AddReversedEdges(); if (cancelManager.IsCancelling) { return; } // compute maxflow var flow = new EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge>( this, this.VisitedGraph, e => 1, this.EdgeFactory ); flow.Compute(augmentor.SuperSource, augmentor.SuperSink); if (cancelManager.IsCancelling) { return; } foreach (var edge in this.VisitedGraph.Edges) { if (flow.ResidualCapacities[edge] == 0) { if (edge.Source.Equals(augmentor.SuperSource) || edge.Source.Equals(augmentor.SuperSource) || edge.Target.Equals(augmentor.SuperSink) || edge.Target.Equals(augmentor.SuperSink)) { //Skip all edges that connect to SuperSource or SuperSink continue; } this.MatchedEdges.Add(edge); } } } finally { if (reverser != null && reverser.Augmented) { reverser.RemoveReversedEdges(); reverser = null; } if (augmentor != null && augmentor.Augmented) { augmentor.Rollback(); augmentor = null; } } }
public void SimpleFlow() { const string source = "A"; const string sink = "G"; var graph = new AdjacencyGraph <string, EquatableTaggedEdge <string, double> >(true); graph.AddVertexRange(new[] { "A", "B", "C", "D", "E", "F", "G" }); // TaggedEdge.Tag is the capacity of the edge graph.AddEdgeRange(new[] { new EquatableTaggedEdge <string, double>("A", "D", 3), new EquatableTaggedEdge <string, double>("A", "B", 3), new EquatableTaggedEdge <string, double>("B", "C", 4), new EquatableTaggedEdge <string, double>("C", "A", 3), new EquatableTaggedEdge <string, double>("C", "D", 1), new EquatableTaggedEdge <string, double>("D", "E", 2), new EquatableTaggedEdge <string, double>("D", "F", 6), new EquatableTaggedEdge <string, double>("E", "B", 1), new EquatableTaggedEdge <string, double>("C", "E", 2), new EquatableTaggedEdge <string, double>("E", "G", 1), new EquatableTaggedEdge <string, double>("F", "G", 9) }); // edgeFactory will be used to create the reversed edges to store residual capacities using the ReversedEdgeAugmentorAlgorithm-class. // The edgeFactory assigns a capacity of 0.0 for the new edges because the initial (residual) capacity must be 0.0. EdgeFactory <string, EquatableTaggedEdge <string, double> > edgeFactory = (sourceNode, targetNode) => new EquatableTaggedEdge <string, double>(sourceNode, targetNode, 0.0); var reverseEdgesAlgorithm = new ReversedEdgeAugmentorAlgorithm <string, EquatableTaggedEdge <string, double> >(graph, edgeFactory); reverseEdgesAlgorithm.AddReversedEdges(); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <string, EquatableTaggedEdge <string, double> >(graph, edge => edge.Tag, edgeFactory, reverseEdgesAlgorithm); algorithm.Compute(source, sink); Assert.AreEqual(source, algorithm.Source); Assert.AreEqual(sink, algorithm.Sink); Assert.AreEqual(5, algorithm.MaxFlow); CheckReversedEdges(); CheckPredecessors(); CheckResidualCapacities(); #region Local function void CheckReversedEdges() { Assert.IsTrue(algorithm.ReversedEdges.Count % 2 == 0); foreach (var pair in algorithm.ReversedEdges) { Assert.AreEqual(pair.Key.Source, pair.Value.Target); Assert.AreEqual(pair.Key.Target, pair.Value.Source); } } void CheckPredecessors() { Assert.AreEqual(graph.VertexCount - 1, algorithm.Predecessors.Count); CollectionAssert.AreEquivalent( new Dictionary <string, EquatableTaggedEdge <string, double> > { ["B"] = new EquatableTaggedEdge <string, double>("A", "B", 3), ["C"] = new EquatableTaggedEdge <string, double>("B", "C", 4), ["D"] = new EquatableTaggedEdge <string, double>("E", "D", 0), ["E"] = new EquatableTaggedEdge <string, double>("C", "E", 2), ["F"] = new EquatableTaggedEdge <string, double>("D", "F", 6), ["G"] = new EquatableTaggedEdge <string, double>("F", "G", 9), }, algorithm.Predecessors); } void CheckResidualCapacities() { Assert.AreEqual(graph.EdgeCount, algorithm.ResidualCapacities.Count); CollectionAssert.AreEquivalent( new Dictionary <EquatableTaggedEdge <string, double>, double> { [new EquatableTaggedEdge <string, double>("A", "B", 3)] = 1, [new EquatableTaggedEdge <string, double>("A", "C", 0)] = 0, [new EquatableTaggedEdge <string, double>("A", "D", 3)] = 0, [new EquatableTaggedEdge <string, double>("B", "A", 0)] = 2, [new EquatableTaggedEdge <string, double>("B", "C", 4)] = 2, [new EquatableTaggedEdge <string, double>("B", "E", 0)] = 0, [new EquatableTaggedEdge <string, double>("C", "A", 3)] = 3, [new EquatableTaggedEdge <string, double>("C", "B", 0)] = 2, [new EquatableTaggedEdge <string, double>("C", "D", 1)] = 0, [new EquatableTaggedEdge <string, double>("C", "E", 2)] = 1, [new EquatableTaggedEdge <string, double>("D", "A", 0)] = 3, [new EquatableTaggedEdge <string, double>("D", "C", 0)] = 1, [new EquatableTaggedEdge <string, double>("D", "E", 2)] = 2, [new EquatableTaggedEdge <string, double>("D", "F", 6)] = 2, [new EquatableTaggedEdge <string, double>("E", "B", 1)] = 1, [new EquatableTaggedEdge <string, double>("E", "C", 0)] = 1, [new EquatableTaggedEdge <string, double>("E", "D", 0)] = 0, [new EquatableTaggedEdge <string, double>("E", "G", 1)] = 0, [new EquatableTaggedEdge <string, double>("F", "D", 0)] = 4, [new EquatableTaggedEdge <string, double>("F", "G", 9)] = 5, [new EquatableTaggedEdge <string, double>("G", "E", 0)] = 1, [new EquatableTaggedEdge <string, double>("G", "F", 0)] = 4, }, algorithm.ResidualCapacities); } #endregion }
protected override void InternalCompute() { this.matchedEdges.Clear(); AllVerticesGraphAugmentorAlgorithm <TVertex, TEdge> augmentor = null; ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverser = null; try { if (this.IsAborting) { return; } //augmenting graph augmentor = new AllVerticesGraphAugmentorAlgorithm <TVertex, TEdge>( this.VisitedGraph, this.VertexFactory, this.EdgeFactory); augmentor.Compute(); if (this.IsAborting) { return; } // adding reverse edges reverser = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>( this.VisitedGraph, this.EdgeFactory ); reverser.AddReversedEdges(); if (this.IsAborting) { return; } // compute maxflow EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge> flow = new EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge>( this.VisitedGraph, AlgoUtility.ConstantCapacities(this.VisitedGraph, 1), reverser.ReversedEdges ); flow.Compute(augmentor.SuperSource, augmentor.SuperSink); if (this.IsAborting) { return; } foreach (TEdge edge in this.VisitedGraph.Edges) { if (this.IsAborting) { return; } if (flow.ResidualCapacities[edge] == 0) { this.matchedEdges.Add(edge); } } } finally { if (reverser != null && reverser.Augmented) { reverser.RemoveReversedEdges(); reverser = null; } if (augmentor != null && augmentor.Augmented) { augmentor.Rollback(); augmentor = null; } } }