算法实现(1):Ford-Fulkerson Algorithm
来源:互联网 发布:php array slice 编辑:程序博客网 时间:2024/05/16 08:51
一、算法介绍
Ford-Fulkerson算法是一种最大流算法,其核心是通过引入“反向边”及“剩余图”的概念对原先的运输方案进行纠错、改进。引用卜东波老师“计算机算法设计与分析”讲义的描述如下:Ford-Fulkerson 算法引入反向边,让运出去的货物还可以有机会退回。将加入了退货边的图称为剩余图,构造剩余图的大致思路为,若 u → v 运了 f 吨货物,且容量限制为 C(u, v),则剩余图中 u 到 v 的正向弧 u → v 权值为 C(u, v) − f,表示最多还可再运 C(u, v) − f 吨货,并构造权值为 f 的反向弧,表示最多可退大小为f 的货物。
例如,下面两个图分别代表网络的流图及剩余图(剩余图中红色的边为“反向边”,即退货边)
Ford-Fulkerson算法过程的示意图如下:
简单来说,就是原始流 + 剩余图中的可行路 = 原始流的一个改进。
二、Pseudo Code
令 p 表示剩余图 Gf 中的一条简单路径,称为增广路径。并定义 bottleneck(p, f) 为路径 p 上的最小容量边。则 Ford-Fulkerson 算法可以描述为:
算法开始,首先将所有边上的流量初始化为零,此时剩余图与原流图相同,然后进入循环,只要在剩余图中存在一条从s(源点)到t(终点)的路径,算法就执行以下步骤:任选一条s-t的路径,确定选择的s-t路径上的bottleneck(即该路径所包含的边的剩余流量的最小值),在该条路径上再流最小的剩余流量(即bottleneck值),最后更新流图及剩余图。直至在剩余图中不存在任何的s到t的路径,终止循环。
三、算法实现
1.实现环境:Windows 8, VS 2010;
2.图的数据结构——邻接矩阵:
本博文对算法的实现过程,采用邻接矩阵存储图信息,邻接矩阵存储图信息的详细过程参阅“图的存储表示——邻接矩阵”;
3.完整程序详见Github,以下记录实现过程的难点:
(1) s-t路径搜索
程序中采用DFS(深度优先)算法搜索剩余图中的s-t路径,实际上是一种递归的思路,不断考察当前节点的邻居节点,看是否能到达终点t,若可以返回true,若不行则返回前一节点并考察前一节点的其他邻居节点。
/************************************************************************/ /* 深度优先遍历(深度优先搜索) */ /************************************************************************/ bool Graph::dfs(int source, bool* visited) { // if current node is the destination node (t), then s-t path is found if(source == nodeNum - 1) return true; int destination; visited[source] = true; for(destination = 0; destination < nodeNum; destination++) // search node adjacent to source { // find adjacent node which has not been visited if(edge[source][destination]>0 && !visited[destination]) { // length of current path increase pathLength += 1; // add adjacent node to s-t path path[pathLength-1] = destination; // go on searching adjacent node if( !(this -> dfs(destination, visited)) ) { // if current adjacent node could not reach the final destinated node // pathLength decrease since it was increased presiously // continue to investigate the next adjacent node pathLength -= 1; continue; } else { // if current adjacent node could reach the final destinated node return true; } } else if(destination == nodeNum - 1) // no adjacent node, means no s-t path return false; }//end for}
(2) 主函数
以前文图示例子作测试,while循环中不断搜索s-t路径,直到剩余图中找不到s-t路径。当存在s-t路径时,如算法所述,取一s-t路径,找bottleneck,更新流与剩余图。
int main(){ // graph wiht node s, u, v, t char nodeName[nodeNum] = {'s', 'u', 'v', 't'}; Graph graph = Graph(nodeNum); graph.setNode(nodeName); graph.setEdge('s', 'u', 1); graph.setEdge('s', 'v', 1); graph.setEdge('u', 'v', 1); graph.setEdge('u', 't', 1); graph.setEdge('v', 't', 1); // Ford-Fulkerson algorithm find maximum flow while(graph.findPath()) { graph.printPath(); graph.findBottleneck(); graph.update(); } // print maximum flow cout << "max flow: " << graph.getFlow() << endl; system("pause"); return 0;}
四、实现结果
打印算法实现的中间结果如下:
- 算法实现(1):Ford-Fulkerson Algorithm
- Ford-Fulkerson算法 java实现
- Ford-Fulkerson算法模板(最大流)
- 最大流算法(Ford-Fulkerson)
- Ford Fulkerson 算法
- [max-flow]ford-fulkerson algorithm (转)
- Ford-Fulkerson algorithm with capacity scaling
- Max bipartite matching with Ford-Fulkerson algorithm
- Edge disjoint paths with Ford-Fulkerson algorithm
- vertex disjoint paths with ford-fulkerson algorithm
- 网络流算法--Ford-Fulkerson方法及其多种实现
- 7. 网络流算法--Ford-Fulkerson方法及其多种实现
- 最大流算法--Ford-Fulkerson方法及其多种实现
- [图论]最大流介绍 Ford-Fulkerson算法 邻接表实现
- 网络流算法--Ford-Fulkerson方法及其多种实现
- 最大流问题-Ford-Fulkerson算法 C++极简实现
- Ford-Fulkerson算法求最大流Java实现
- 网络流算法--FORD-FULKERSON方法及其多种实现
- Class和Style绑定
- (9)Java多线程之Lock接口
- 深入MNIST code测试
- Android 仿IOS版QQ实现下拉刷新水滴的效果
- map, foreach, for的用法区别
- 算法实现(1):Ford-Fulkerson Algorithm
- 动态数码管
- 杂项记录
- 基于MFC的实时可视化项目中视图刷新消息的严谨使用
- android-ndk环境配置
- hdu5296 01字典树
- javaEE防盗版-前言
- Java基本概念-多态
- web使垂直居中的方法