Beispiel #1
0
        public void TestBigGraph()
        {
            IWeightedGraph <int, double> graph = LoadGraphFromFile("./graphs/weighted/G_1_2.txt");
            IVertex <int> source = graph.GetFirstMatchingVertex(v => v.Value == 0);
            IVertex <int> target = graph.GetFirstMatchingVertex(v => v.Value == 7);
            IWeightedGraph <int, double> maxFlow = EdmondsKarp.FindMaxFlow(graph, source, target, CombineFlowValues, SubstractFlowValues, 0.0);
            double maxFlowValue = GetMaxFlowValue(maxFlow, source.Value);

            AssertDoublesNearlyEqual(0.735802, maxFlowValue, 0.000001);
        }
Beispiel #2
0
        public void TestSmallGraph()
        {
            IWeightedGraph <int, double> graph = LoadGraphFromFile("./graphs/max_flow/Fluss2.txt");
            IVertex <int> source = graph.GetFirstMatchingVertex(v => v.Value == 0);
            IVertex <int> target = graph.GetFirstMatchingVertex(v => v.Value == 7);
            IWeightedGraph <int, double> maxFlow = EdmondsKarp.FindMaxFlow(graph, source, target, CombineFlowValues, SubstractFlowValues, 0.0);
            double maxFlowValue = GetMaxFlowValue(maxFlow, source.Value);

            Assert.AreEqual(5, maxFlowValue);
        }
    public void FindMaxFlow_WithCrossGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 1000, 1000, 0 },
            new int[] { 0, 0, 1, 1000 },
            new int[] { 0, 0, 0, 1000 },
            new int[] { 0, 0, 0, 0 },
        };
        var expected = 2000;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
    static void Main(string[] args)
    {
        var graph = new int[][]
        {
            new int[] { 0, 10, 10, 0, 0, 0 },
            new int[] { 0, 0, 2, 4, 8, 0 },
            new int[] { 0, 0, 0, 0, 9, 0 },
            new int[] { 0, 0, 0, 0, 0, 10 },
            new int[] { 0, 0, 0, 6, 0, 10 },
            new int[] { 0, 0, 0, 0, 0, 0 },
        };

        var maxFlow = EdmondsKarp.FindMaxFlow(graph);

        Console.WriteLine($"Max flow = {maxFlow}");
    }
    public void FindMaxFlow_WithSmallGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 10, 10, 0, 0, 0 },
            new int[] { 0, 0, 2, 4, 8, 0 },
            new int[] { 0, 0, 0, 0, 9, 0 },
            new int[] { 0, 0, 0, 0, 0, 10 },
            new int[] { 0, 0, 0, 6, 0, 10 },
            new int[] { 0, 0, 0, 0, 0, 0 },
        };

        var expected = 19;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
        static void Main(string[] args)
        {
            CapacityGraph g = new CapacityGraph(new int[, ]
            {
                { 0, 7, 1 },
                { 7, 0, 3 },
                { 1, 3, 0 }
            });

            g.setSourceNode(0);
            g.setSinkNode(2);

            int maxFlow = EdmondsKarp.FindMaxFlow(g.getCapacityMatrix(), g.getNeighbors(), g.getSourceNode(), g.getSinkNode());

            Console.WriteLine($"Max flow = {maxFlow}");

            Console.WriteLine("\n\nPress any key to continue...\n\n");
            Console.ReadKey();
        }
    public void FindMaxFlow_WithMediumGraphWithBackwardsEdges()
    {
        var graph = new int[][]
        {
            new int[] { 0, 0, 3, 5, 17, 0, 5, 0 },
            new int[] { 0, 0, 2, 13, 0, 0, 7, 0 },
            new int[] { 0, 6, 0, 9, 3, 13, 0, 0 },
            new int[] { 0, 0, 3, 0, 17, 10, 5, 0 },
            new int[] { 0, 15, 0, 8, 0, 6, 6, 9 },
            new int[] { 0, 0, 22, 0, 3, 0, 7, 10 },
            new int[] { 0, 5, 0, 9, 4, 13, 0, 5 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0 },
        };

        var expected = 24;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
    public void FindMaxFlow_WithMediumGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 6, 15, 5, 0, 0, 0, 0 },
            new int[] { 0, 0, 7, 0, 8, 0, 0, 3 },
            new int[] { 0, 0, 0, 9, 9, 13, 0, 0 },
            new int[] { 0, 0, 0, 3, 17, 10, 5, 0 },
            new int[] { 0, 0, 0, 0, 0, 0, 11, 8 },
            new int[] { 0, 0, 0, 0, 0, 0, 7, 12 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 14 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0 },
        };

        var expected = 26;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
    public void FindMaxFlow_WithLargeGraph()
    {
        var graph = new int[][]
        {
            new int[] { 0, 0, 0, 0, 0, 0, 30, 0, 22, 0, 0, 0 },             // 0
            new int[] { 0, 0, 0, 0, 20, 0, 0, 26, 0, 25, 0, 6 },            // 1
            new int[] { 0, 0, 0, 0, 0, 0, 0, 15, 14, 0, 0, 9 },             // 2
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0 },               // 3
            new int[] { 0, 20, 0, 0, 0, 5, 17, 0, 0, 0, 0, 11 },            // 4
            new int[] { 0, 0, 0, 0, 5, 0, 6, 0, 3, 0, 0, 33 },              // 5
            new int[] { 30, 0, 0, 0, 17, 6, 0, 0, 0, 0, 0, 0 },             // 6
            new int[] { 0, 26, 15, 0, 0, 0, 0, 0, 0, 23, 0, 20 },           // 7
            new int[] { 22, 0, 14, 0, 0, 3, 0, 0, 0, 0, 0, 0 },             // 8
            new int[] { 0, 25, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0 },             // 9
            new int[] { 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0 },               // 10
            new int[] { 0, 6, 9, 0, 11, 33, 0, 20, 0, 0, 0, 0 },            // 11
        };

        var expected = 40;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
    public void FindMaxFlow_WithLargeGraphWithBackwardsEdges()
    {
        var graph = new int[][]
        {
            new int[] { 0, 13, 55, 8, 0, 13, 0, 0, 15, 0, 5, 0, 0 },
            new int[] { 0, 0, 155, 13, 21, 0, 0, 0, 14, 0, 35, 0, 0 },
            new int[] { 0, 3, 0, 44, 0, 15, 0, 0, 47, 0, 56, 0, 14 },
            new int[] { 0, 77, 0, 0, 0, 71, 28, 90, 99, 5, 0, 76, 0 },
            new int[] { 0, 0, 15, 7, 0, 64, 3, 0, 15, 0, 65, 0, 43 },
            new int[] { 0, 23, 0, 5, 17, 0, 5, 0, 51, 3, 86, 0, 0 },
            new int[] { 0, 33, 33, 0, 0, 7, 0, 13, 0, 6, 17, 8, 34 },
            new int[] { 0, 0, 0, 0, 0, 0, 5, 0, 5, 5, 5, 5, 5 },
            new int[] { 0, 5, 0, 0, 27, 13, 34, 0, 21, 57, 42, 0, 71 },
            new int[] { 0, 287, 15, 31, 49, 0, 70, 0, 13, 0, 99, 13, 0 },
            new int[] { 0, 0, 44, 1, 17, 0, 5, 0, 15, 0, 0, 29, 0 },
            new int[] { 0, 44, 4, 13, 19, 14, 0, 0, 34, 0, 12, 0, 0 },
            new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        };

        var expected = 109;
        var maxFlow  = EdmondsKarp.FindMaxFlow(graph);

        Assert.AreEqual(expected, maxFlow, $"Expected {expected}, but was {maxFlow}.");
    }
Beispiel #11
0
        public static IEnumerable <IEdge <TV> > FindMaxMatching <TV>(IGraph <TV> graph,
                                                                     ISet <IVertex <TV> > set1,
                                                                     ISet <IVertex <TV> > set2,
                                                                     TV superSourceValue,
                                                                     TV superTargetValue) where TV : IEquatable <TV>
        {
            // Build directed graph with super nodes and capacity 1
            IWeightedGraph <TV, int> graphWithSuperNodes = BuildGraphWithSuperNodesAndCapacity(graph, superSourceValue, superTargetValue, set1, set2, 1);
            IVertex <TV>             sourceNode          = graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superSourceValue));
            IVertex <TV>             targetNode          = graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superTargetValue));

            // Compute max flow in graph with super nodes
            IWeightedGraph <TV, int> maxFlow = EdmondsKarp.FindMaxFlow(graphWithSuperNodes,
                                                                       sourceNode,
                                                                       targetNode,
                                                                       (x, y) => x + y,
                                                                       (x, y) => x - y,
                                                                       0);

            // Add edges with flow to matching
            List <IEdge <TV> > matchings = new List <IEdge <TV> >();

            foreach (IVertex <TV> vertex in set1)
            {
                foreach (IEdge <TV> edge in graph.GetEdgesOfVertex(vertex))
                {
                    if (maxFlow.GetEdgeBetweenVerteces(vertex.Value, edge.ConnectedVertex(vertex).Value).Weight == 1)
                    {
                        matchings.Add(edge);
                    }
                }
            }

            // Done - return matching!
            return(matchings);
        }
Beispiel #12
0
        public static IWeightedGraph <TV, TW> FindCostMinimalFlow <TV, TW>(IWeightedGraph <TV, TW> graph,
                                                                           TV superSourceValue,
                                                                           TV superTargetValue,
                                                                           Func <TW, TW, TW> combineValues,
                                                                           Func <TW, TW, TW> substractValues,
                                                                           Func <TW, TW> negateValue,
                                                                           TW zeroValue,
                                                                           TW maxValue)
            where TV : IEquatable <TV> where TW : IComparable
        {
            // Build graph with super nodes
            IWeightedGraph <TV, TW> graphWithSuperNodes = BuildGraphWithSuperNodes(graph, superSourceValue, superTargetValue, negateValue);

            // Get max flow in graph with super nodes
            IWeightedGraph <TV, TW> maxFlow = EdmondsKarp.FindMaxFlow(graphWithSuperNodes,
                                                                      graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superSourceValue)),
                                                                      graphWithSuperNodes.GetFirstMatchingVertex(v => v.Value.Equals(superTargetValue)),
                                                                      combineValues,
                                                                      substractValues,
                                                                      zeroValue);
            TW maxFlowValue = FlowValue(maxFlow, superSourceValue, combineValues, zeroValue);

            // Check for existance of a b-flow
            IEnumerable <IVertex <TV> > sources = graph.GetAllMatchingVerteces(v => v.GetAttribute <double>(Constants.BALANCE) > 0);
            IEnumerable <IVertex <TV> > targets = graph.GetAllMatchingVerteces(v => v.GetAttribute <double>(Constants.BALANCE) < 0);
            TW sourcesBalance = zeroValue;
            TW targetsBalance = zeroValue;

            foreach (IVertex <TV> source in sources)
            {
                sourcesBalance = combineValues(sourcesBalance, source.GetAttribute <TW>(Constants.BALANCE));
            }
            foreach (IVertex <TV> target in targets)
            {
                targetsBalance = combineValues(targetsBalance, target.GetAttribute <TW>(Constants.BALANCE));
            }
            if (maxFlowValue.Equals(sourcesBalance) &&
                maxFlowValue.Equals(negateValue(targetsBalance)))
            {
                // Copy flow values from graph with super nodes to original graph
                foreach (IWeightedEdge <TV, TW> edge in graphWithSuperNodes.GetAllEdges())
                {
                    if (edge is IWeightedDirectedEdge <TV, TW> directedEdge)
                    {
                        if (!directedEdge.OriginVertex.Value.Equals(superSourceValue) &&
                            !directedEdge.TargetVertex.Value.Equals(superTargetValue))
                        {
                            graph.GetEdgeBetweenVerteces(directedEdge.OriginVertex.Value, directedEdge.TargetVertex.Value)
                            .SetAttribute(Constants.FLOW, edge.GetAttribute <TW>(Constants.FLOW));
                        }
                    }
                    else
                    {
                        throw new GraphNotDirectedException();
                    }
                }

                bool modifyingCycleLeft;
                do
                {
                    // Build residual graph
                    IWeightedGraph <TV, TW> residualGraph = BuildResidualGraph(graph, substractValues, negateValue, zeroValue);

                    // Prepare graph for BellmanFordMoore
                    IWeightedGraph <TV, TW> bfmGraph = BuildGraphForBellmanFordMoore(residualGraph, superSourceValue, zeroValue);

                    // Attempt to find modifying cycle
                    IVertex <TV> bfmSuperSource = bfmGraph.GetFirstMatchingVertex(v => v.Value.Equals(superSourceValue));
                    if (modifyingCycleLeft = BellmanFordMoore.TryFindNegativeCycle(bfmGraph,
                                                                                   bfmSuperSource,
                                                                                   zeroValue,
                                                                                   maxValue,
                                                                                   combineValues,
                                                                                   out IEnumerable <IWeightedDirectedEdge <TV, TW> > cycle))
                    {
                        // Get minimum capacity of the cycle in the residual graph
                        List <IWeightedDirectedEdge <TV, TW> > rgCycle = new List <IWeightedDirectedEdge <TV, TW> >();
                        foreach (IWeightedDirectedEdge <TV, TW> edge in cycle)
                        {
                            rgCycle.Add((IWeightedDirectedEdge <TV, TW>)residualGraph.GetEdgeBetweenVerteces(edge.OriginVertex.Value, edge.TargetVertex.Value));
                        }
                        TW minCycleCapacity = rgCycle.Min(e => e.Weight);

                        // Modify b-flow along cycle
                        foreach (IWeightedDirectedEdge <TV, TW> edge in rgCycle)
                        {
                            if (edge.GetAttribute <EdgeDirection>(Constants.DIRECTION) == EdgeDirection.Forward)
                            {
                                IWeightedDirectedEdge <TV, TW> graphEdge = (IWeightedDirectedEdge <TV, TW>)graph.GetEdgeBetweenVerteces(edge.OriginVertex.Value, edge.TargetVertex.Value);
                                graphEdge.SetAttribute(Constants.FLOW, combineValues(graphEdge.GetAttribute <TW>(Constants.FLOW), minCycleCapacity));
                            }
                            else
                            {
                                IWeightedDirectedEdge <TV, TW> graphEdge = (IWeightedDirectedEdge <TV, TW>)graph.GetEdgeBetweenVerteces(edge.TargetVertex.Value, edge.OriginVertex.Value);
                                graphEdge.SetAttribute(Constants.FLOW, substractValues(graphEdge.GetAttribute <TW>(Constants.FLOW), minCycleCapacity));
                            }
                        }
                    }
                }while (modifyingCycleLeft);

                // Return same graph
                return(graph);
            }
            else
            {
                throw new NoBFlowException();
            }
        }