private void CleanForward(FlowNetwork Lf,Verticle v) { if(v.NumOfEdgesIn==0) foreach(Edge e in v.EdgesOut.ToList()){ Lf.G.RemoveEdge(e); CleanForward(Lf,e.To); } }
private void CleanSaturatedEdges(FlowNetwork Lf,Func<Edge,int> f,List<Edge> path) { foreach(Edge e in path) if(f(e) == Lf.c(e)){ Lf.G.RemoveEdge(e); CleanForward(Lf,e.To); } }
//Assuming there is a path between s and t in Nf, and BFS was already done private FlowNetwork BuildLayeredNetwork(FlowNetwork Nf) { Graph Lf = new Graph(); int numOfLayers = Nf.G.GetVerticle(tId).Dist; foreach(Edge e in Nf.G.Edges) if(e.To.Dist <= numOfLayers && e.From.Dist+1 == e.To.Dist) Lf.AddEdge(e); return new FlowNetwork(Lf,Nf.c,sId,tId); }
private Func<Edge,int> FindBlockingFlow(FlowNetwork Lf) { Func<Edge,int> b = (e=>0); Verticle t = Lf.G.GetVerticle(tId); List<Edge> path; Func<Edge,int> g; while(t.NumOfEdgesIn>0) { path = FindBackwardPath(Lf.G,sId,tId); g = FindPathFlow(path,Lf.c); b = AddFlow(b,g); CleanSaturatedEdges(Lf,b,path); Lf.G.Bfs(sId); } return b; }
public Func<Edge,int> EdmondKarp(Func<Edge,int> f) { Contract.Requires(f!=null); FlowNetwork Nf = BuildResidualNetwork(f); Nf.G.Bfs(sId); List<Edge> path; Func<Edge,int> g; while(Nf.G.GetVerticle(tId).Dist<int.MaxValue) { path = Nf.G.GetShortestPath(sId,tId,statsReady:true); g = FindPathFlow(path,Nf.c); f = AddFlow(f,g); Nf = BuildResidualNetwork(f); Nf.G.Bfs(sId); } return f; }
public Func<Edge,int> Dinitz(Func<Edge,int> f) { Contract.Requires(f!=null); FlowNetwork Nf = BuildResidualNetwork(f); Nf.G.Bfs(sId); FlowNetwork Lf = BuildLayeredNetwork(Nf); Func<Edge,int> b; while(Nf.G.GetVerticle(tId).Dist<int.MaxValue) { b = FindBlockingFlow(Lf); f = AddFlow(f,b); Nf = BuildResidualNetwork(f); Nf.G.Bfs(sId); Lf = BuildLayeredNetwork(Nf); } return f; }