[Maxflow Mincut] Coursera Maxflow Mincut 最大流最小割集
2017-03-02 10:07
591 查看
最近在忙项目,闲下来一天时间,继续学习Cousera上的Algorithm,这本大红书真是好用,比严某某的不知道高到那里去了,而且真心应该看英文原版。
最大流问题的本质在于寻找一条augmenting path form source to end,每找到一条augmenting path就可以使flow增加,所谓的augmenting path是一条从source 到end的无向路径,其中可以包含前向通路(forward path not full)和后向通路(backward path not empty),所以流程如下
利用BFS或者DFS或者最短路径算法 寻找一条送source到end的无向路径(undirected path)
检查该路径是否满足augmenting path的要求,如满足,则循路径方向increase forward path decrease backward path并寻找其中的瓶颈,
如此往复直到没有augmenting path 得出最后的Maxflow
MinCut可以从Source出发,寻找与之相连并且forward path not full,backward path not empty的点即可
本次课程的编程作业是来计算棒球比赛赛程进行一段时间后,是否有球队因为成绩太差,无论后期如何,都会提前出局。
主要的思想在于建立一个剩余比赛的网络,然后求其最大流及相应割集,割集中的节点就是导致该响应队伍出局的原因。难点在于如何形成network,解MAxflow可以直接调用函数库
最大流问题的本质在于寻找一条augmenting path form source to end,每找到一条augmenting path就可以使flow增加,所谓的augmenting path是一条从source 到end的无向路径,其中可以包含前向通路(forward path not full)和后向通路(backward path not empty),所以流程如下
利用BFS或者DFS或者最短路径算法 寻找一条送source到end的无向路径(undirected path)
检查该路径是否满足augmenting path的要求,如满足,则循路径方向increase forward path decrease backward path并寻找其中的瓶颈,
如此往复直到没有augmenting path 得出最后的Maxflow
MinCut可以从Source出发,寻找与之相连并且forward path not full,backward path not empty的点即可
本次课程的编程作业是来计算棒球比赛赛程进行一段时间后,是否有球队因为成绩太差,无论后期如何,都会提前出局。
主要的思想在于建立一个剩余比赛的网络,然后求其最大流及相应割集,割集中的节点就是导致该响应队伍出局的原因。难点在于如何形成network,解MAxflow可以直接调用函数库
import edu.princeton.cs.algs4.Bag; import edu.princeton.cs.algs4.FlowEdge; import edu.princeton.cs.algs4.FlowNetwork; import edu.princeton.cs.algs4.FordFulkerson; import edu.princeton.cs.algs4.In; import edu.princeton.cs.algs4.ST; import edu.princeton.cs.algs4.StdOut; public class BaseballElimination { private final int[] w; private final int[] l; private final int[] r; private final int[][] g; private final ST<String, Integer> teams; private final ST<Integer,String> reverseInt; private final int N; private final boolean[] isElimated; private final Bag<String>[] subsets; @SuppressWarnings("unchecked") public BaseballElimination(String filename){ // create a baseball division from given filename in format specified below In in = new In(filename); N = in.readInt(); w = new int ; l = new int ; r = new int ; reverseInt = new ST<Integer,String>(); isElimated = new boolean ; teams = new ST<String,Integer>(); g = new int ; subsets = (Bag<String>[]) new Bag ; for (int q = 0; q < N; q++) subsets[q] = new Bag<String>(); int i = 0; while (!in.isEmpty()){ String tmp = in.readString(); teams.put(tmp,i); reverseInt.put(i,tmp); w[i] = in.readInt(); l[i] = in.readInt(); r[i] = in.readInt(); for(int j = 0; j < N ; j++){ g[i][j] = in.readInt(); } i++; } for(int ii = 0; ii<N;ii++ ){ int sum = w[ii] + r[ii]; for(int m = 0; m < N; m++){ if(sum < w[m]){ isElimated[ii] = true; subsets[ii].add(reverseInt.get(m)); } } } for(int index = 0;index < N; index ++){ if(isElimated[index]==true) continue; FlowNetwork flowNet = formFlowNet(index); FordFulkerson maxflow = new FordFulkerson(flowNet, N + (N - 2) * (N - 1) /2, N + (N - 2) * (N - 1) /2 + 1); for (int v = 0; v < N; v++) { if(N == index) continue; if (maxflow.inCut(v)){ isElimated[index] = true; subsets[index].add(reverseInt.get(v)); } } } } private FlowNetwork formFlowNet(int index){ FlowNetwork flownet = new FlowNetwork(N + (N - 2) * (N - 1) /2 + 2); int i = N; for(int row =0;row < N && i != N + (N - 2) * (N - 1) /2; row++){ if(row == index) continue; int col = row + 1; for(; col < N; col++){ if(col == index) continue; flownet.addEdge(new FlowEdge(N + (N - 2) * (N - 1) / 2,i,g[row][col])); flownet.addEdge(new FlowEdge(i,row,Double.POSITIVE_INFINITY)); flownet.addEdge(new FlowEdge(i,col,Double.POSITIVE_INFINITY)); i++; } } for(int j =0;j<N;j++){ if(j != index){ flownet.addEdge(new FlowEdge(j,N + (N - 2) * (N - 1) /2 + 1,w[index] + r[index] - w[j] )); } } return flownet; } public int numberOfTeams(){ // number of teams return N; } public Iterable<String> teams(){ // all teams return teams.keys(); } public int wins(String team){ // number of wins for given team if(w == null) throw new NullPointerException(); if(!teams.contains(team)) throw new IllegalArgumentException(); return w[teams.get(team)]; } public int losses(String team){ // number of losses for given team if(l == null) throw new NullPointerException(); if(!teams.contains(team)) throw new IllegalArgumentException(); return l[teams.get(team)]; } public int remaining(String team){ // number of remaining games for given team if(r == null) throw new NullPointerException(); if(!teams.contains(team)) throw new IllegalArgumentException(); return r[teams.get(team)]; } public int against(String team1, String team2){ // number of remaining games between team1 and team2 if(g == null) throw new NullPointerException(); if(!teams.contains(team1) || !teams.contains(team2)) throw new IllegalArgumentException(); int i = teams.get(team1); int j = teams.get(team2); return g[i][j]; } public boolean isEliminated(String team){ // is given team eliminated? if(!teams.contains(team)) throw new IllegalArgumentException(); if(isElimated == null) throw new NullPointerException(); return isElimated[teams.get(team)]; } public Iterable<String> certificateOfElimination(String team) { // subset R of teams that eliminates given team; null if not eliminated if(!teams.contains(team)) throw new IllegalArgumentException(); if(!isElimated[teams.get(team)]) return null; return subsets[teams.get(team)]; } public static void main(String[] args) { BaseballElimination division = new BaseballElimination(args[0]); for (String team : division.teams()) { if (division.isEliminated(team)) { StdOut.print(team + " is eliminated by the subset R = { "); for (String t : division.certificateOfElimination(team)) { StdOut.print(t + " "); } StdOut.println("}"); } else { StdOut.println(team + " is not eliminated"); } } } }
相关文章推荐
- 最大流/最小割(maxflow/mincut)的原理讲解和代码实现
- maxflow mincut 最大流最小割
- matlab实现图割算法中的最大流最小割Max-flow/min-cut问题(一)
- Max Flow / Min Cut 最大流最小割算法学习
- 最大流/最小割(maxflow/mincut)的原理讲解和代码实现
- CV | Max Flow / Min Cut 最大流最小割算法学习
- matlab实现图割算法中的最大流最小割Max-flow/min-cut问题(一)
- Grab Cut 源码解读(最大流-最小割, min-cut\max-flow)
- CV | Max Flow / Min Cut 最大流最小割算法学习
- 关于Yuri Boykov and Vladimir Kolmogorov 于2004年提出的max flow / min cut的算法的详解
- max flow ans min cut
- 最大流最小割定理(max flow/min cut theory)
- 最大流最小割定理(max flow/min cut theory)
- 最大流最小割定理(max flow/min cut theory)
- Princeton Algorithms: Part 2 [week 3: Maxflow and Mincut]
- Menger's Theorems and Max-Flow-Min-Cut
- 关于Yuri Boykov and Vladimir Kolmogorov 于2004年提出的max flow / min cut的算法的详解
- 最大流最小割定理(max flow/min cut theory)
- 关于Yuri Boykov and Vladimir Kolmogorov 于2004年提出的max flow / min cut的算法的详解
- 关于Yuri Boykov and Vladimir Kolmogorov 于2004年提出的max flow / min cut的算法的详解