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
        }
示例#2
0
        /// <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
        }
示例#4
0
        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
        }
示例#5
0
 public void ConstructorWithNullGraph()
 {
     this.target = new ReversedEdgeAugmentorAlgorithm(null);
 }
示例#6
0
        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();
                }
            }
        }