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); }
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}."); }
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); }
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(); } }