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 }
/// <inheritdoc /> protected override void InternalCompute() { BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge> augmentor = null; ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverser = null; try { ThrowIfCancellationRequested(); // Augmenting the graph augmentor = new BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge>( this, VisitedGraph, SourceToVertices, VerticesToSink, VertexFactory, EdgeFactory); augmentor.Compute(); ThrowIfCancellationRequested(); // Adding reverse edges reverser = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>( VisitedGraph, EdgeFactory); reverser.AddReversedEdges(); ThrowIfCancellationRequested(); // Compute maximum flow var flow = new EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge>( this, VisitedGraph, edge => 1.0, EdgeFactory, reverser); flow.Compute(augmentor.SuperSource, augmentor.SuperSink); ThrowIfCancellationRequested(); foreach (TEdge edge in VisitedGraph.Edges) { if (Math.Abs(flow.ResidualCapacities[edge]) < float.Epsilon) { if (EqualityComparer <TVertex> .Default.Equals(edge.Source, augmentor.SuperSource) || EqualityComparer <TVertex> .Default.Equals(edge.Source, augmentor.SuperSink) || EqualityComparer <TVertex> .Default.Equals(edge.Target, augmentor.SuperSource) || EqualityComparer <TVertex> .Default.Equals(edge.Target, 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(); } } }
public void Constructor_Throws() { var graph1 = new AdjacencyGraph <int, Edge <int> >(); var graph2 = new AdjacencyGraph <int, Edge <int> >(); Func <Edge <int>, double> capacities = edge => 1.0; EdgeFactory <int, Edge <int> > edgeFactory = (source, target) => new Edge <int>(source, target); var reverseEdgesAlgorithm1 = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph1, edgeFactory); var reverseEdgesAlgorithm2 = new ReversedEdgeAugmentorAlgorithm <int, Edge <int> >(graph2, edgeFactory); // ReSharper disable ObjectCreationAsStatement // ReSharper disable AssignNullToNotNullAttribute Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, capacities, edgeFactory, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, null, edgeFactory, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, capacities, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, capacities, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, edgeFactory, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, capacities, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, capacities, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, null, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, null, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, capacities, null, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, capacities, null, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, null, null, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, null, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, capacities, edgeFactory, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, graph1, null, edgeFactory, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, graph1, capacities, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, graph1, capacities, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, null, edgeFactory, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, capacities, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, capacities, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, graph1, null, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, graph1, null, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, graph1, capacities, null, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, null, null, reverseEdgesAlgorithm1)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, null, edgeFactory, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, capacities, null, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, graph1, null, null, null)); Assert.Throws <ArgumentNullException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(null, null, null, null, null)); // ReSharper restore AssignNullToNotNullAttribute Assert.Throws <ArgumentException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph1, capacities, edgeFactory, reverseEdgesAlgorithm2)); Assert.Throws <ArgumentException>( () => new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >(graph2, capacities, edgeFactory, reverseEdgesAlgorithm1)); // ReSharper restore ObjectCreationAsStatement }
public void Constructor() { var graph = new AdjacencyGraph <int, Edge <int> >(); 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); var algorithm = new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >( graph, capacities, edgeFactory, reverseEdgesAlgorithm); AssertAlgorithmProperties( algorithm, graph, capacities, edgeFactory); algorithm = new EdmondsKarpMaximumFlowAlgorithm <int, Edge <int> >( null, graph, capacities, edgeFactory, reverseEdgesAlgorithm); AssertAlgorithmProperties( algorithm, graph, capacities, edgeFactory); #region Local function void AssertAlgorithmProperties <TVertex, TEdge>( EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge> algo, IMutableVertexAndEdgeListGraph <TVertex, TEdge> g, Func <TEdge, double> c, EdgeFactory <int, Edge <int> > eFactory) where TEdge : IEdge <TVertex> { AssertAlgorithmState(algo, g); CollectionAssert.IsEmpty(algo.Predecessors); Assert.AreSame(c, algo.Capacities); CollectionAssert.IsEmpty(algo.ResidualCapacities); if (eFactory is null) { Assert.IsNotNull(algo.EdgeFactory); } else { Assert.AreSame(eFactory, algo.EdgeFactory); } CollectionAssert.IsEmpty(algo.ReversedEdges); Assert.AreEqual(default(TVertex), algo.Source); Assert.AreEqual(default(TVertex), algo.Sink); Assert.AreEqual(0.0, algo.MaxFlow); CollectionAssert.IsEmpty(algo.VerticesColors); } #endregion }
public void ConstructorWithNullGraph() { this.target = new ReversedEdgeAugmentorAlgorithm(null); }
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; } //#if !SILVERLIGHT // this.VisitedGraph.OpenAsDGML("before.dgml"); //#endif //augmenting graph augmentor = new BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge>( this, this.VisitedGraph, this.VertexSetA, this.VertexSetB, this.VertexFactory, this.EdgeFactory); augmentor.Compute(); if (cancelManager.IsCancelling) { return; } //#if !SILVERLIGHT // this.VisitedGraph.OpenAsDGML("afteraugment.dgml"); //#endif //adding reverse edges reverser = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>( this.VisitedGraph, this.EdgeFactory ); reverser.AddReversedEdges(); if (cancelManager.IsCancelling) { return; } //#if !SILVERLIGHT // this.VisitedGraph.OpenAsDGML("afterreversal.dgml"); //#endif // 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) { if (augmentor.Augmented) { augmentor.Rollback(); } augmentor.Dispose(); augmentor = null; } } }
protected override void InternalCompute() { var cancelManager = this.Services.CancelManager; this.matchedEdges.Clear(); AllVerticesGraphAugmentorAlgorithm <TVertex, TEdge> augmentor = null; ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverser = null; try { if (cancelManager.IsCancelling) { return; } //augmenting graph augmentor = new AllVerticesGraphAugmentorAlgorithm <TVertex, TEdge>( this, this.VisitedGraph, 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, AlgoUtility.ConstantCapacities(this.VisitedGraph, 1), reverser.ReversedEdges ); flow.Compute(augmentor.SuperSource, augmentor.SuperSink); if (cancelManager.IsCancelling) { return; } foreach (var edge in this.VisitedGraph.Edges) { if (cancelManager.IsCancelling) { 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; } } }
/// <inheritdoc /> protected override void InternalCompute() { ICancelManager cancelManager = Services.CancelManager; MatchedEdges.Clear(); 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, 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(); } } }