public void MaxFlowTwiceTest() { var fg = new FlowGraph(3); Assert.That(fg.AddEdge(0, 1, 1), Is.Zero); Assert.That(fg.AddEdge(0, 2, 1), Is.EqualTo(1)); Assert.That(fg.AddEdge(1, 2, 1), Is.EqualTo(2)); Assert.That(fg.MaxFlow(0, 2), Is.EqualTo(2)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 1))); fg.ChangeEdge(0, 100, 10); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 100, 10))); Assert.That(fg.MaxFlow(0, 2), Is.Zero); Assert.That(fg.MaxFlow(0, 1), Is.EqualTo(90)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 100, 100))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 1))); Assert.That(fg.MaxFlow(2, 0), Is.EqualTo(2)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 100, 99))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 0))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 0))); }
static int[] FindMatching(bool[][] bipartiteGraph) { int numLeft = bipartiteGraph.Length; int numRight = bipartiteGraph[0].Length; int[] matching = new int[numLeft]; FlowGraph graph = ReadGraph(bipartiteGraph); MaxFlow(graph, 0, graph.Size() - 1); for (int i = 0; i < numLeft; i++) { foreach (int id in graph.GetIds(i + 1)) { Edge edge = graph.GetEdge(id); if (edge.flow == 1) { matching[i] = edge.to - numLeft; break; } matching[i] = -1; } } return(matching); }
public void MinCostFlowSelfLoopTest() { var fg = new FlowGraph(3); Assert.That(fg.AddEdge(0, 0, 100, 123), Is.Zero); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 0, 100, 0, 123))); }
public void MaxFlowMinCutTest() { var fg = new FlowGraph(3); Assert.That(fg.AddEdge(0, 1, 2), Is.Zero); Assert.That(fg.AddEdge(1, 2, 1), Is.EqualTo(1)); Assert.That(fg.MaxFlow(0, 2), Is.EqualTo(1)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 2, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 1))); var minCut = fg.MinCut(0); Assert.That(minCut[0], Is.True); Assert.That(minCut[1], Is.True); Assert.That(minCut[2], Is.False); }
public void ArgumentOutOfRangeExceptionInAddEdgeAndGetEdge([Values(-1, 3)] int v) { var fg = new FlowGraph(3); Assert.Throws <ArgumentOutOfRangeException>(() => fg.AddEdge(v, 1, 10)); Assert.Throws <ArgumentOutOfRangeException>(() => fg.AddEdge(0, v, 10)); Assert.Throws <ArgumentOutOfRangeException>(() => fg.GetEdge(v)); }
public void MaxFlowSimpleTest() { var fg = new FlowGraph(4); Assert.That(fg.AddEdge(0, 1, 1), Is.Zero); Assert.That(fg.AddEdge(0, 2, 1), Is.EqualTo(1)); Assert.That(fg.AddEdge(1, 3, 1), Is.EqualTo(2)); Assert.That(fg.AddEdge(2, 3, 1), Is.EqualTo(3)); Assert.That(fg.AddEdge(1, 2, 1), Is.EqualTo(4)); Assert.That(fg.MaxFlow(0, 3), Is.EqualTo(2)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 3, 1, 1))); Assert.That(fg.GetEdge(3), Is.EqualTo(new FlowGraph.Edge(2, 3, 1, 1))); Assert.That(fg.GetEdge(4), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 0))); }
public void MinCostFlowSimpleTest() { var fg = new FlowGraph(4); fg.AddEdge(0, 1, 1, 1); fg.AddEdge(0, 2, 1, 1); fg.AddEdge(1, 3, 1, 1); fg.AddEdge(2, 3, 1, 1); fg.AddEdge(1, 2, 1, 1); var actual = fg.MinCostSlope(0, 3, 10).ToArray(); Assert.That(actual[0], Is.EqualTo((0, 0))); Assert.That(actual[1], Is.EqualTo((2, 4))); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 3, 1, 1, 1))); Assert.That(fg.GetEdge(3), Is.EqualTo(new FlowGraph.Edge(2, 3, 1, 1, 1))); Assert.That(fg.GetEdge(4), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 0, 1))); }
public void MaxFlowComplexTest() { var fg = new FlowGraph(2); Assert.That(fg.AddEdge(0, 1, 1), Is.Zero); Assert.That(fg.AddEdge(0, 1, 2), Is.EqualTo(1)); Assert.That(fg.AddEdge(0, 1, 3), Is.EqualTo(2)); Assert.That(fg.AddEdge(0, 1, 4), Is.EqualTo(3)); Assert.That(fg.AddEdge(0, 1, 5), Is.EqualTo(4)); Assert.That(fg.AddEdge(0, 0, 6), Is.EqualTo(5)); Assert.That(fg.AddEdge(1, 1, 7), Is.EqualTo(6)); Assert.That(fg.MaxFlow(0, 1), Is.EqualTo(15)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 1, 2, 2))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(0, 1, 3, 3))); Assert.That(fg.GetEdge(3), Is.EqualTo(new FlowGraph.Edge(0, 1, 4, 4))); Assert.That(fg.GetEdge(4), Is.EqualTo(new FlowGraph.Edge(0, 1, 5, 5))); var minCut = fg.MinCut(0); Assert.That(minCut[0], Is.True); Assert.That(minCut[1], Is.False); }
public static FlowGraph <T> FordFulkerson <T>(this FlowGraph <T> graph) { if (graph.Edges.Where(e => !e.Capacity.HasValue).Any()) { throw new ArgumentException("In dem Graphen muss für jede Kante eine Kapazität definiert sein."); } // Sicherstellen, dass der Fluss bei allen Kanten initialisiert ist. foreach (Edge <T> e in graph.Edges.Where(e => !e.Flow.HasValue)) { e.Flow = 0; } // Eine Kopie des Graphens erstellen. FlowGraph <T> maxFlowGraph = graph.Copy(); // Den Residualgraph erstellen FlowGraph <T> residualGraph = maxFlowGraph.GetResidualGraph(); while (residualGraph.DepthFirstSearch(residualGraph.Source, residualGraph.Target, out List <Edge <T> > path)) { int minAugmentingFlow = path.Select(e => Math.Abs(e.Flow.Value)).Min(); foreach (Edge <T> edge in path) { //Edge<T> edgeToModify = maxFlowGraph.Edges.Where(e => e.From.Equals(edge.From) && e.To.Equals(edge.To)).Single(); Edge <T> edgeToModify = maxFlowGraph.GetEdge(edge.From, edge.To); if (edge.Flow.Value > 0) { edgeToModify.Flow += minAugmentingFlow; } else { edgeToModify.Flow -= minAugmentingFlow; } // edgeToModify.Flow += edge.Flow; } residualGraph = maxFlowGraph.GetResidualGraph(); } return(maxFlowGraph); }
static void MaxFlow(FlowGraph graph, int from, int to) { while (true) { bool foundPath = false; var queue = new Queue <int>(); var parentIds = new int[graph.Size()]; for (int i = 0; i < parentIds.Length; i++) { parentIds[i] = -1; //unvisited nodes are -1 } queue.Enqueue(0); //Breadth-first search, finding shortest path while (queue.Count != 0 && !foundPath) { int node = queue.Dequeue(); var ids = graph.GetIds(node); // all the edges from current node foreach (int id in ids) { var edge = graph.GetEdge(id); if (edge.flow < edge.capacity && parentIds[edge.to] == -1) // if there's capacity left and "edge pointing" vertice isn't visited { if (edge.to == edge.from) { continue; } parentIds[edge.to] = id; if (edge.to == graph.Size() - 1) // we found path { foundPath = true; break; } queue.Enqueue(edge.to); } } } if (!foundPath) { break; } //find the value of the flow to = graph.Size() - 1; var minCap = -1; //calculate min capacity while (to != 0) { var id = parentIds[to]; var edge = graph.GetEdge(id); if (minCap == -1 || (edge.capacity - edge.flow) < minCap) { minCap = edge.capacity - edge.flow; } to = edge.from; } to = graph.Size() - 1; //adding flow to edges while (to != 0) { var id = parentIds[to]; var edge = graph.GetEdge(id); graph.AddFlow(id, minCap); to = edge.from; } } }
public void LoadFlowGraph_must_work() { string path = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName, "TestFiles", "FlowGraph.txt"); FlowGraph <string> graph = (FlowGraph <string>)GraphGenerator.LoadFromFile(path); // Die Vertices prüfen Assert.IsTrue(graph.HasEdge(new Vertex <string>("s"), new Vertex <string>("a"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("s"), new Vertex <string>("b"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("a"), new Vertex <string>("b"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("a"), new Vertex <string>("c"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("b"), new Vertex <string>("c"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("b"), new Vertex <string>("d"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("c"), new Vertex <string>("d"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("c"), new Vertex <string>("t"))); Assert.IsTrue(graph.HasEdge(new Vertex <string>("d"), new Vertex <string>("t"))); // Die Kapzitäten und Flüsse prüfen. Assert.AreEqual(5, graph.GetEdge(new Vertex <string>("s"), new Vertex <string>("a")).Capacity); Assert.AreEqual(5, graph.GetEdge(new Vertex <string>("s"), new Vertex <string>("a")).Flow); Assert.AreEqual(7, graph.GetEdge(new Vertex <string>("s"), new Vertex <string>("b")).Capacity); Assert.AreEqual(3, graph.GetEdge(new Vertex <string>("s"), new Vertex <string>("b")).Flow); Assert.AreEqual(7, graph.GetEdge(new Vertex <string>("a"), new Vertex <string>("b")).Capacity); Assert.AreEqual(3, graph.GetEdge(new Vertex <string>("a"), new Vertex <string>("b")).Flow); Assert.AreEqual(4, graph.GetEdge(new Vertex <string>("a"), new Vertex <string>("c")).Capacity); Assert.AreEqual(2, graph.GetEdge(new Vertex <string>("a"), new Vertex <string>("c")).Flow); Assert.AreEqual(3, graph.GetEdge(new Vertex <string>("b"), new Vertex <string>("c")).Capacity); Assert.AreEqual(3, graph.GetEdge(new Vertex <string>("b"), new Vertex <string>("c")).Flow); Assert.AreEqual(3, graph.GetEdge(new Vertex <string>("b"), new Vertex <string>("d")).Capacity); Assert.AreEqual(3, graph.GetEdge(new Vertex <string>("b"), new Vertex <string>("d")).Flow); Assert.AreEqual(4, graph.GetEdge(new Vertex <string>("c"), new Vertex <string>("d")).Capacity); Assert.AreEqual(0, graph.GetEdge(new Vertex <string>("c"), new Vertex <string>("d")).Flow); Assert.AreEqual(5, graph.GetEdge(new Vertex <string>("c"), new Vertex <string>("t")).Capacity); Assert.AreEqual(5, graph.GetEdge(new Vertex <string>("c"), new Vertex <string>("t")).Flow); Assert.AreEqual(6, graph.GetEdge(new Vertex <string>("d"), new Vertex <string>("t")).Capacity); Assert.AreEqual(3, graph.GetEdge(new Vertex <string>("d"), new Vertex <string>("t")).Flow); }
static int MaxFlow(FlowGraph graph, int from, int to) { int flow = 0; while (true) { bool foundPath = false; var queue = new Queue <int>(); var parentIds = new int[graph.Size()]; for (int i = 0; i < parentIds.Length; i++) { parentIds[i] = -1; //unvisited nodes are -1 } queue.Enqueue(0); //bfs while (queue.Count != 0 && !foundPath) { int node = queue.Dequeue(); var ids = graph.GetIds(node); // all the edges from current node foreach (int id in ids) { var edge = graph.GetEdge(id); if (edge.flow < edge.capacity && parentIds[edge.to] == -1) { if (edge.to == edge.from) { continue; } parentIds[edge.to] = id; if (edge.to == graph.Size() - 1) // we found path { foundPath = true; break; } queue.Enqueue(edge.to); } } } if (!foundPath) { break; } //find the value of the flow to = graph.Size() - 1; var minCap = -1; //calculate min capacity while (to != 0) { var id = parentIds[to]; var edge = graph.GetEdge(id); if (minCap == -1 || (edge.capacity - edge.flow) < minCap) { minCap = edge.capacity - edge.flow; } to = edge.from; } to = graph.Size() - 1; //adding flow to edges while (to != 0) { var id = parentIds[to]; var edge = graph.GetEdge(id); graph.AddFlow(id, minCap); to = edge.from; } } //calculate the flow // to do that we only sum the flows of the start node foreach (int id in graph.GetIds(0)) { var edge = graph.GetEdge(id); flow += edge.flow; } return(flow); }