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); }
static void Main(string[] args) { Console.Write("Enter the number of test cases to run: "); int test = int.Parse(Console.ReadLine()); Console.WriteLine("* * * * * * * * * * * * Dinic * * * * * * * * * * * *"); TestDinic.Test(test); Console.WriteLine("* * * * * * * * * * Edmonds Karp * * * * * * * * * *"); EdmondsKarp.Test(test); Console.WriteLine("* * * * * * * * * Ford Fulkerson * * * * * * * * *"); FordFloukerson.Test(test); }
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}."); }
public void ComputeMaximalMatching(WeightedDiAdjacencyMatrix graph) { List <int> redVerticles = null; List <int> blueVerticles = null; if (!IsGraphBipartite(graph, out redVerticles, out blueVerticles)) { Console.WriteLine("Graph is not Bipartite!"); return; } WeightedDiAdjacencyMatrix diGraph = new WeightedDiAdjacencyMatrix(graph.Order + 2); int S = 1; int T = graph.Order + 2; for (int i = 1; i <= graph.Order; i++) { var neighbours = graph.Neighbours(i); foreach (var item in neighbours) { if (blueVerticles.Contains(i)) { diGraph.AddEdge(i + 1, item + 1, 1f); } } } blueVerticles.ForEach(blue => diGraph.AddEdge(S, blue + 1, 1f)); redVerticles.ForEach(red => diGraph.AddEdge(red + 1, T, 1f)); Console.WriteLine("Residual network S=0; T=" + (T - 1)); for (int i = 0; i < diGraph.Order; i++) { Console.Write("Neighbours[" + (i) + "]\t"); diGraph.Neighbours(i + 1).ForEach(_ => Console.Write((_ - 1) + " ")); Console.WriteLine(); } Console.WriteLine("To read result remove S-> and ->T. Then substract 1 from each middle N->N:"); var edmondsKarp = new EdmondsKarp(); edmondsKarp.MaximumFlow(diGraph, S - 1, T - 1); }
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 static IWeightedGraph <TV, TW> BuildResidualGraph <TV, TW>(IWeightedGraph <TV, TW> graph, Func <TW, TW, TW> substractValues, Func <TW, TW> negateValue, TW zeroValue) where TV : IEquatable <TV> where TW : IComparable { // Build residual graph as done in Edmonds-Karp IWeightedGraph <TV, TW> residualGraph = EdmondsKarp.BuildResidualGraph(graph, substractValues, zeroValue); // Add costs foreach (IWeightedEdge <TV, TW> edge in graph.GetAllEdges()) { if (edge is IWeightedDirectedEdge <TV, TW> directedEdge) { TW costs = edge.GetAttribute <TW>(Constants.COSTS); // Add costs to forward edges if (residualGraph.AreVertecesConnected(directedEdge.OriginVertex.Value, directedEdge.TargetVertex.Value)) { residualGraph.GetEdgeBetweenVerteces(directedEdge.OriginVertex.Value, directedEdge.TargetVertex.Value) .SetAttribute(Constants.COSTS, costs); } // Add negative costs to backward edges if (residualGraph.AreVertecesConnected(directedEdge.TargetVertex.Value, directedEdge.OriginVertex.Value)) { residualGraph.GetEdgeBetweenVerteces(directedEdge.TargetVertex.Value, directedEdge.OriginVertex.Value) .SetAttribute(Constants.COSTS, negateValue(costs)); } } else { throw new GraphNotDirectedException(); } } // Done - return residual graph return(residualGraph); }
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 void Main(string[] args) { Data data = DataProvider.Instance.ReadData("DateProblema.txt"); Retea retea = new Retea(); int nrNoduri = data.NrAsociatii + data.NrLocuitori + data.NrPartidePolitice + 2; Nod nodSursa = new Nod { Id = 1, EsteNodSursa = true, EsteNodStoc = false, }; Nod nodStoc = new Nod { Id = nrNoduri, EsteNodSursa = false, EsteNodStoc = true, }; retea.Noduri.Add(nodSursa); int idNodCurent = nodSursa.Id; data.Asociatii.ForEach(asociatie => { Nod nodAsociatie = retea.Noduri.FirstOrDefault(n => n.IdAsociatie == asociatie.Id); if (nodAsociatie == null) { idNodCurent++; nodAsociatie = new Nod { Id = idNodCurent, IdAsociatie = asociatie.Id }; retea.Noduri.Add(nodAsociatie); } Arc arc = new Arc(nodSursa, nodAsociatie, flux: 0, capacitate: 1); retea.Arce.Add(arc); }); data.Locuitori.ForEach(locuitor => { Nod nodLocuitor = retea.Noduri.FirstOrDefault(n => n.IdLocuitor == locuitor.Id); if (nodLocuitor == null) { idNodCurent++; nodLocuitor = new Nod { Id = idNodCurent, IdLocuitor = locuitor.Id }; retea.Noduri.Add(nodLocuitor); } List <Asociatie> asociatii = data.Asociatii.Where(asociatie => asociatie.Membrii.Contains(locuitor)).ToList(); asociatii.ForEach(asociatie => { Nod nodAsociatie = retea.Noduri.FirstOrDefault(n => n.IdAsociatie == asociatie.Id); if (nodAsociatie == null) { throw new InvalidOperationException($"Nu a fost creat nod pentru asociatia cu id-ul {asociatie.Id}."); } Arc arc = new Arc(nodAsociatie, nodLocuitor, 0, 1); retea.Arce.Add(arc); }); }); List <Arc> arcePartide = new List <Arc>(); data.PartidePolitice.ForEach(partid => { Nod nodPartid = retea.Noduri.FirstOrDefault(n => n.IdPartid == partid.Id); if (nodPartid == null) { idNodCurent++; nodPartid = new Nod { Id = idNodCurent, IdPartid = partid.Id }; retea.Noduri.Add(nodPartid); } partid.Membrii.ForEach(locuitor => { Nod nodLocuitor = retea.Noduri.FirstOrDefault(n => n.IdLocuitor == locuitor.Id); if (nodLocuitor == null) { throw new InvalidOperationException($"Nu a fost creat nod pentru locuitorul cu id-ul {locuitor.Id}."); } retea.Arce.Add(new Arc(nodLocuitor, nodPartid, 0, 1)); }); Arc arc = new Arc(nodPartid, nodStoc, flux: 0, capacitate: partid.NrReprezentantiInConsiliu); arcePartide.Add(arc); }); retea.Arce.AddRange(arcePartide); data.Locuitori.ForEach(locuitor => { IEnumerable <PartidPolitic> partide = data.PartidePolitice.Where(p => p.Membrii.Contains(locuitor)); if (partide?.Count() == 0) { Nod nodLocuitor = retea.Noduri.FirstOrDefault(n => n.IdLocuitor == locuitor.Id); if (nodLocuitor == null) { throw new InvalidOperationException($"Nu a fost creat nod pentru locuitorul cu id-ul {locuitor.Id}."); } retea.Arce.Add(new Arc(nodLocuitor, nodStoc, 0, 1)); } }); retea.Noduri.Add(nodStoc); EdmondsKarp edmondsKarp = new EdmondsKarp(); AhujaOrlin ahujaOrlin = new AhujaOrlin(); PrefluxFIFO prefluxFIFO = new PrefluxFIFO(); double maxValue = -1; string option = string.Empty; while (true) { Console.WriteLine("Selectati algoritmul: "); Console.WriteLine("1. Edmonds Karp"); Console.WriteLine("2. Preflux FIFO"); Console.WriteLine("3. Iesire program"); string input = Console.ReadLine(); switch (input.Trim()) { case "1": maxValue = edmondsKarp.GetValoareMaxima(new Retea(retea)); break; case "2": maxValue = prefluxFIFO.GetValoareMaxima(new Retea(retea)); break; case "3": default: return; } Console.WriteLine($"Valoarea maxima: {maxValue}"); Console.WriteLine($"Consiliul orasului {((maxValue == data.NrAsociatii) ? "" : "NU ")}este echilibrat!"); Console.ReadKey(); } }
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(); } }