//Creates a new FlowNetwork, sets it as the current graph public FlowNetwork NewFlowNetwork(string name) { FlowNetwork g = new FlowNetwork(); g.Name = name; graphs.Add(g); currentGraph = g; return g; }
//Creates a new FlowNetwork, sets it as the current graph public FlowNetwork NewFlowNetwork(string name) { FlowNetwork g = new FlowNetwork(); g.Name = name; graphs.Add(g); currentGraph = g; return(g); }
public static Graph CreateResidualNetwork(FlowNetwork fn) { FlowNetwork copy = new FlowNetwork(); fn.CopyTo(copy); Graph g = new Graph(); g.Directed = true; for (int i = 0; i < copy.GetVertices().Count; i++) { Vertex v = copy.GetVertices()[i]; v.Tag = i; v.RemoveAllEdges(); g.AddVertex(v); } foreach (FlowEdge e in copy.GetEdges()) { float backflow = e.CurrentFlow; float capacity = e.Capacity; float forwardFlow = capacity - backflow; Vertex fromVertex = e.GetFromVertex(); Vertex toVertex = e.GetToVertex(); int fromIndex = (int)fromVertex.Tag; int toindex = (int)toVertex.Tag; Vertex newTo = g.GetVertices()[toindex]; Vertex newFrom = g.GetVertices()[fromIndex]; if (backflow > 0) { Edge backEdge = new Edge(newTo, newFrom, backflow); g.AddEdge(backEdge); } if (forwardFlow > 0) { Edge forwardEdge = new Edge(newFrom, newTo, forwardFlow); g.AddEdge(forwardEdge); } } return(g); }
private void copyLinkedGraph(FlowNetwork to) { to.Clear(); for (int i = 0; i < this.GetVertices().Count; i++) { vertices[i].Tag = i; Vertex v = new Vertex(); v.Tag = i; to.AddVertex(v); } for (int i = 0; i < this.GetEdges().Count; i++) { Edge currentEdge = this.GetEdges()[i]; Vertex v1 = new Vertex(); v1.Label = currentEdge.GetFromVertex().Label; int cd = (int)currentEdge.GetFromVertex().Tag; if ((int)to.GetVertices()[cd].Tag == cd) { v1 = to.GetVertices()[cd]; } Vertex v2 = new Vertex(); v2.Label = currentEdge.GetToVertex().Label; int cd2 = (int)currentEdge.GetToVertex().Tag; if ((int)to.GetVertices()[cd2].Tag == cd2) { v2 = to.GetVertices()[cd2]; } FlowEdge fe = currentEdge as FlowEdge; Edge e = new FlowEdge(v1, v2, fe.CurrentFlow, fe.Capacity); to.AddEdge(e); } FlowNetwork fn = this as FlowNetwork; if (fn != null) { to.SetSource(fn.GetSource()); to.SetSink(fn.GetSink()); } }
public static float MaximumFlow(FlowNetwork fn, int source, int sink) { float maxFlow = 0f; int sourceIndex = source; int sinkIndex = sink; foreach (FlowEdge e in fn.GetEdges()) { e.CurrentFlow = 0f; } Graph g = CreateResidualNetwork(fn); List<Edge> augmentingPath = BreadthFirstSearch(g, sourceIndex, sinkIndex); while (augmentingPath != null) { float minFlow = float.MaxValue; //find min flow foreach (Edge e in augmentingPath) { if (e.Weight < minFlow) { minFlow = e.Weight; } } maxFlow += minFlow; foreach (Edge e in augmentingPath) { //Update residual graph Edge currentForwardResid = g.FindEdge(e); Edge currentBackwardResid = g.FindEdge(new Edge(e.GetToVertex(), e.GetFromVertex())); float newForwardWeight = currentForwardResid.Weight - minFlow; if (newForwardWeight <= 0f) { g.RemoveEdge(currentForwardResid); } else { currentForwardResid.Weight = newForwardWeight; } if (currentBackwardResid != null) { float newBackwardWeight = currentBackwardResid.Weight + minFlow; currentBackwardResid.Weight = newBackwardWeight; } else { currentBackwardResid = new Edge(e.GetToVertex(), e.GetFromVertex(), minFlow); g.AddEdge(currentBackwardResid); } //Update flow network FlowEdge fe = fn.FindEdge(new FlowEdge(e.GetFromVertex(), e.GetToVertex(), 0, 0)); fe.CurrentFlow = fe.CurrentFlow + minFlow; } augmentingPath = BreadthFirstSearch(g, sourceIndex, sinkIndex); //augmentingPath = null; } return maxFlow; }
public static Graph CreateResidualNetwork(FlowNetwork fn) { FlowNetwork copy = new FlowNetwork(); fn.CopyTo(copy); Graph g = new Graph(); g.Directed = true; for (int i = 0; i < copy.GetVertices().Count; i++) { Vertex v = copy.GetVertices()[i]; v.Tag = i; v.RemoveAllEdges(); g.AddVertex(v); } foreach (FlowEdge e in copy.GetEdges()) { float backflow = e.CurrentFlow; float capacity = e.Capacity; float forwardFlow = capacity - backflow; Vertex fromVertex = e.GetFromVertex(); Vertex toVertex = e.GetToVertex(); int fromIndex = (int)fromVertex.Tag; int toindex = (int)toVertex.Tag; Vertex newTo = g.GetVertices()[toindex]; Vertex newFrom = g.GetVertices()[fromIndex]; if (backflow > 0) { Edge backEdge = new Edge(newTo, newFrom, backflow); g.AddEdge(backEdge); } if (forwardFlow > 0) { Edge forwardEdge = new Edge(newFrom, newTo, forwardFlow); g.AddEdge(forwardEdge); } } return g; }
private static void TestResidualNetwork() { //Create graph from Figure 6.10 FlowNetwork fn = new FlowNetwork(); Vertex v1 = new Vertex(); Vertex v2 = new Vertex(); Vertex v3 = new Vertex(); Vertex v4 = new Vertex(); fn.AddVertex(v1); fn.AddVertex(v2); fn.AddVertex(v3); fn.AddVertex(v4); fn.SetSource(v1); fn.SetSink(v4); fn.AddEdge(new FlowEdge(v1, v3, 3, 4)); fn.AddEdge(new FlowEdge(v1, v2, 2, 2)); fn.AddEdge(new FlowEdge(v2, v3, 2, 3)); fn.AddEdge(new FlowEdge(v3, v4, 5, 5)); fn.AddEdge(new FlowEdge(v2, v4, 0, 1)); Graph g = GraphAlgorithms.CreateResidualNetwork(fn); }
private static void TestMaxFlow() { FlowNetwork fn = new FlowNetwork(); Vertex v1 = new Vertex(); Vertex v2 = new Vertex(); Vertex v3 = new Vertex(); Vertex v4 = new Vertex(); Vertex v5 = new Vertex(); Vertex v6 = new Vertex(); fn.AddVertex(v1); fn.AddVertex(v2); fn.AddVertex(v3); fn.AddVertex(v4); fn.AddVertex(v5); fn.AddVertex(v6); fn.SetSource(v1); fn.SetSink(v6); fn.AddEdge(new FlowEdge(v1, v2, 0f, 2f)); fn.AddEdge(new FlowEdge(v1, v3, 0f, 2f)); fn.AddEdge(new FlowEdge(v2, v4, 0f, 2f)); fn.AddEdge(new FlowEdge(v3, v4, 1f, 2f)); fn.AddEdge(new FlowEdge(v3, v5, 0f, 2f)); fn.AddEdge(new FlowEdge(v4, v6, 1f, 2f)); fn.AddEdge(new FlowEdge(v5, v6, 0f, 2f)); //float maxFlow = GraphAlgorithms.MaximumFlow(fn); //Console.WriteLine("Max flow is " + maxFlow); }
public static float MaximumFlow(FlowNetwork fn, int source, int sink) { float maxFlow = 0f; int sourceIndex = source; int sinkIndex = sink; foreach (FlowEdge e in fn.GetEdges()) { e.CurrentFlow = 0f; } Graph g = CreateResidualNetwork(fn); List <Edge> augmentingPath = BreadthFirstSearch(g, sourceIndex, sinkIndex); while (augmentingPath != null) { float minFlow = float.MaxValue; //find min flow foreach (Edge e in augmentingPath) { if (e.Weight < minFlow) { minFlow = e.Weight; } } maxFlow += minFlow; foreach (Edge e in augmentingPath) { //Update residual graph Edge currentForwardResid = g.FindEdge(e); Edge currentBackwardResid = g.FindEdge(new Edge(e.GetToVertex(), e.GetFromVertex())); float newForwardWeight = currentForwardResid.Weight - minFlow; if (newForwardWeight <= 0f) { g.RemoveEdge(currentForwardResid); } else { currentForwardResid.Weight = newForwardWeight; } if (currentBackwardResid != null) { float newBackwardWeight = currentBackwardResid.Weight + minFlow; currentBackwardResid.Weight = newBackwardWeight; } else { currentBackwardResid = new Edge(e.GetToVertex(), e.GetFromVertex(), minFlow); g.AddEdge(currentBackwardResid); } //Update flow network FlowEdge fe = fn.FindEdge(new FlowEdge(e.GetFromVertex(), e.GetToVertex(), 0, 0)); fe.CurrentFlow = fe.CurrentFlow + minFlow; } augmentingPath = BreadthFirstSearch(g, sourceIndex, sinkIndex); //augmentingPath = null; } return(maxFlow); }