예제 #1
0
        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());
        }
예제 #2
0
        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);
        }
예제 #3
0
 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);
 }
예제 #4
0
        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));
        }
예제 #5
0
        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);
        }
예제 #6
0
 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);
 }
예제 #7
0
        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());
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #16
0
        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));
        }
예제 #17
0
        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));
        }
예제 #18
0
        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());
        }
예제 #19
0
        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);
        }
예제 #20
0
        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);
        }
예제 #21
0
        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();
        }
예제 #22
0
        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();
                }
            }
        }
예제 #24
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;
                }


                //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;
                }
            }
        }
예제 #25
0
        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
        }
예제 #26
0
        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;
                }
            }
        }