对最大流算法Ford

合集下载

最大流算法研究FordFulkerson和EdmondsKarp算法

最大流算法研究FordFulkerson和EdmondsKarp算法

最大流算法研究FordFulkerson和EdmondsKarp算法最大流算法是图论中一个重要的概念和研究领域,它用于解决网络流问题。

在最大流问题中,我们需要找到从源节点到汇节点的最大流量,以便在网络中实现最优的数据传输。

本文将研究两种经典的最大流算法:FordFulkerson算法和EdmondsKarp算法。

1. FordFulkerson算法FordFulkerson算法是由L.R.Ford Jr.和D.R.Fulkerson于1956年提出的经典算法。

该算法基于贪心思想,通过不断寻找增广路径来逐步增加流量,直到达到最大流。

算法步骤如下:1.1 初始化网络中的流量为0。

1.2 找到一条从源节点到汇节点的增广路径。

1.3 计算增广路径上的最小容量。

1.4 将最小容量加到网络中的流量上,并更新相关边的残余容量。

1.5 重复步骤2和步骤3,直到无法找到增广路径。

FordFulkerson算法的核心思想是不断寻找增广路径,并在每次找到增广路径时增加流量,直到无法找到增广路径为止。

该算法的时间复杂度取决于增广路径的数量和最大容量的大小,最坏情况下可以达到O(E|f*|),其中E是网络中的边数,|f*|是最大流的大小。

2. EdmondsKarp算法EdmondsKarp算法是FordFulkerson算法的一个改进版本,由J.Edmonds和R.Karp于1972年提出。

该算法利用广度优先搜索来寻找增广路径,从而减少了搜索路径的数量,提高了算法的效率。

算法步骤如下:2.1 初始化网络中的流量为0。

2.2 使用广度优先搜索来寻找从源节点到汇节点的最短增广路径。

2.3 计算增广路径上的最小容量。

2.4 将最小容量加到网络中的流量上,并更新相关边的残余容量。

2.5 重复步骤2和步骤3,直到无法找到增广路径。

EdmondsKarp算法的核心思想是利用广度优先搜索来寻找增广路径,从而减少搜索路径的数量,提高算法的效率。

最大流问题解题步骤

最大流问题解题步骤

最大流问题解题步骤一、什么是最大流问题?最大流问题是指在一个有向图中,给定源点和汇点,每条边都有一个容量限制,求从源点到汇点的最大流量。

该问题可以用于网络传输、电力调度等实际应用中。

二、最大流问题的解法1. 增广路算法增广路算法是最基本的解决最大流问题的方法。

其基本思想是不断地寻找增广路,并将其上的流量加入到原来的流中,直到不存在增广路为止。

具体步骤如下:(1)初始化网络中各边上的流量均为0;(2)在残留网络中寻找增广路;(3)如果存在增广路,则将其上的最小剩余容量作为增量加入到原来的流中;(4)重复步骤2和步骤3,直到不存在增广路。

2. Dinic算法Dinic算法是一种改进型的增广路算法,其核心思想是通过层次分析和分层图来减少搜索次数,进而提高效率。

具体步骤如下:(1)构建分层图;(2)在分层图上进行BFS搜索寻找增广路径;(3)计算路径上可行流量并更新残留网络;(4)重复步骤2和步骤3,直到不存在增广路。

3. Ford-Fulkerson算法Ford-Fulkerson算法是一种基于增广路的算法,其核心思想是不断地寻找增广路,并将其上的流量加入到原来的流中,直到不存在增广路为止。

具体步骤如下:(1)初始化网络中各边上的流量均为0;(2)在残留网络中寻找增广路;(3)如果存在增广路,则将其上的最小剩余容量作为增量加入到原来的流中;(4)重复步骤2和步骤3,直到不存在增广路。

三、最大流问题解题步骤1. 确定源点和汇点首先需要确定问题中的源点和汇点,这是解决最大流问题的前提条件。

2. 构建残留网络在有向图中,每条边都有一个容量限制。

我们可以将这些边看作管道,容量看作管道的宽度。

在实际传输过程中,某些管道可能已经被占用了一部分宽度。

因此,在求解最大流问题时,需要构建一个残留网络来表示哪些管道还能够继续传输数据。

具体方法是:对于每条边(u,v),分别构造两条边(u,v)和(v,u),容量分别为c(u,v)-f(u,v)和f(u,v),其中c(u,v)表示边的容量,f(u,v)表示当前流量。

最大流常见算法

最大流常见算法

最大流常见算法最大流问题是图论中的一个重要问题,其求解方法有多种,本文将介绍最常见的几种算法。

一、最大流问题简介最大流问题是在一个网络中寻找从源点到汇点的最大流量的问题。

网络是由一些节点和连接这些节点的边构成的,每条边都有一个容量,表示该边所能承载的最大流量。

源点是流量的起点,汇点是流量的终点。

在网络中,还可能存在其他节点和边。

二、Ford-Fulkerson算法Ford-Fulkerson算法是最早用于解决最大流问题的算法之一。

该算法基于增广路径来不断增加流量,直到无法再找到增广路径为止。

1. 算法步骤(1)初始化:将所有边上的流量设为0。

(2)寻找增广路径:从源点开始进行深度优先或广度优先搜索,在搜索过程中只选择剩余容量不为0且没有被标记过的边,并记录路径上容量最小值min。

(3)更新路径上各个边上的流量:将路径上各个边上的流量加上min。

(4)返回第二步,直到无法找到增广路径为止。

2. 算法分析Ford-Fulkerson算法可以保证在有限步内求解出最大流,但是其时间复杂度与增广路径的选择有关,最坏情况下可能需要指数级的时间复杂度。

三、Edmonds-Karp算法Edmonds-Karp算法是基于Ford-Fulkerson算法的一种改进算法。

该算法使用BFS来寻找增广路径,可以保证在多项式时间内求解出最大流。

1. 算法步骤(1)初始化:将所有边上的流量设为0。

(2)寻找增广路径:从源点开始进行BFS,在搜索过程中只选择剩余容量不为0且没有被标记过的边,并记录路径上容量最小值min。

(3)更新路径上各个边上的流量:将路径上各个边上的流量加上min。

(4)返回第二步,直到无法找到增广路径为止。

2. 算法分析Edmonds-Karp算法相对于Ford-Fulkerson算法来说,在同样的网络中,其时间复杂度更低,可以保证在O(VE^2)的时间内求解出最大流。

但是在某些特殊情况下仍然可能需要指数级时间复杂度。

最大流算法及其应用

最大流算法及其应用

最大流算法及其应用随着社会经济的发展和科技的进步,许多问题需要通过优化算法来解决,最大流算法就是其中之一。

最大流算法是在一个有向图中找到从源点到汇点的最大可能流的算法。

该算法在网络设计,交通流量控制,通信网络等领域有着广泛的应用。

1. 最大流问题在一个有向图G=(V,E)中,包含源点s和汇点t,每条边(u,v)上有一个容量c,表示该边的最大流量。

现要从源点到汇点流过尽可能多的流量,问最大可能的流量是多少?这就是最大流问题,寻找的答案是最大流量F。

2. 最大流算法最大流算法有多种实现方法,其中最著名的是 Ford-Fulkerson算法。

该算法的核心是寻找增广路径。

增广路径是一条从源点到汇点的路径,并且在该路径上所有边的容量都大于0。

通过将增广路径上的每一条边的流量都增加相同的值,就可以增加当前的流量。

重复这个过程直到不能再找到增广路径为止。

算法的详细步骤如下:1. 初始化所有边流量为0。

2. 查找增广路径。

可以使用深度优先搜索或广度优先搜索实现。

每找到一条增广路径就更新整个图的流量。

3. 重复步骤 2 直到无法再找到增广路径。

4. 输出最大流F。

该算法的时间复杂度不稳定,最差情况下是指数级的,但是由于增广路径的挖掘和流量的增加都是“往前走一步”,因此这种最长路径的情况是非常少见的。

在实际应用中,最大流算法基本上可以忽略这种情况。

3. 最大流算法应用(1) 网络设计在网络设计中,如果可以量化每个设备之间的容量,比如光缆的传输带宽,那么就可以使用最大流算法确定网络的最大传输能力。

如果网络的总传输能力超过了最大数据需求,那么可以减少设备之间的传输带宽,从而节省成本。

(2) 交通流量控制在城市交通中,最大流算法可以用来确定道路的拥堵情况,以及交叉路口的物流控制。

在公路建设中,如果能够准确地预测车辆数量和流量,就可以使用最大流算法确定道路的最大承载能力,从而保证交通的顺畅。

(3) 通信网络最大流算法也可以用于网络协议的设计。

Ford-Fulkerson算法

Ford-Fulkerson算法

1、Ford-Fulkerson 算法 算法描述: STEP0:置初始可行流。

STEP1:构造原网络的残量网络,在残量网络中找s -t 有向路。

如果没有,算法得到最大流结束。

否则继续下一步。

STEP2:依据残量网络中的s -t 有向路写出对应到原网络中的s -t 增广路。

对于增广路中的前向弧,置s(e) ←u(e)- f(e)。

对于反向弧,置s(e) ←f (e )。

STEP3:计算crement=min{s (e 1),s (e 2),…,s (e k )};STEP4:对于增广路中的前向弧,令f(e) ←f(e)+crement ;对于其中的反向弧,令f(e)←f(e)-crement ,转STEP1。

这里f 代表弧上的当前流量,s 表示弧上可增广的量。

在STEP2的残量网络中,寻找s -t 有向路的算法有两种,DFS 和BFS ,即深度优先和宽度优先算法。

算法的时间复杂度为O(mnU)。

其中m 为弧的数目,U 为弧上容量的最大上界,是伪多项式算法。

邻接表表示图,空间复杂度为O(n+m)。

DFS 和BFS 的比较例子:图4.8.6假设M 是弧上的最大容量,且是一个非常大的整数,DFS 算法的最坏情况会选择S ->A ->B ->T 和S ->B ->A ->T 进行增广,增广的次数为2M ,这个问题用BFS 算法,沿S ->A ->T 和S ->B ->T 增广两次就可以完成。

见图4.8.6。

2、最大容量增广路算法Ford-Fulkerson 算法每次只是在所有增广路中随机地找一条增广路进行增广,因此增广的次数可能很多。

如果每次都找到一条可增广的容量最大的增广路,则总的增广次数应当减少,这样的算法称为最大容量增广路算法。

最大容量增广路算法寻找增广路的步骤如下:STEP0:将s 点可增广值maxf 标记为一个非常大的数,其他节点的maxf 值为0,所有节点标记为未扩展。

数据结构之的最大流算法FordFulkerson算法原理和实现

数据结构之的最大流算法FordFulkerson算法原理和实现

数据结构之的最大流算法FordFulkerson算法原理和实现数据结构之最大流算法Ford-Fulkerson算法原理和实现最大流算法是图算法中的一种重要算法,被应用于解决许多实际问题,例如电力分配、网络流量优化等。

Ford-Fulkerson算法是最经典的最大流算法之一,下面将详细介绍其原理和实现。

一、Ford-Fulkerson算法原理Ford-Fulkerson算法基于残余网络的概念来寻找增广路径,通过不断地增加流量来求解最大流问题。

它的基本思想是在图中找到一条从源点到汇点的路径,并在该路径上增加流量,直到没有增广路径为止。

具体步骤如下:1. 初始化流网络:将每条边的流量设置为0。

2. 在残余网络中找到增广路径:使用深度优先搜索或广度优先搜索来寻找一条从源点到汇点的路径。

残余网络中的边是指原有流量未满的边以及流量超过了容量的边。

3. 计算路径上的最小流量:在增广路径中找到最小的残余容量,记为min_flow。

4. 更新路径上的流量:将路径上的每条边的流量增加min_flow。

5. 更新残余容量:对于每条增广路径上的边,更新其残余容量。

原有流量未满的边的残余容量等于该边的容量减去当前流量,流量超过容量的边的残余容量为0。

6. 重复步骤2-5直到没有增广路径。

7. 最大流量即为源点流出的总流量。

二、Ford-Fulkerson算法实现下面以Python语言为例,给出Ford-Fulkerson算法的实现。

```pythonclass Graph:def __init__(self, graph):self.graph = graphself.row = len(graph)def bfs(self, s, t, parent):visited = [False] * self.rowqueue = []queue.append(s)visited[s] = Truewhile queue:u = queue.pop(0)for idx, val in enumerate(self.graph[u]):if visited[idx] == False and val > 0:queue.append(idx)visited[idx] = Trueparent[idx] = uif idx == t:return Truereturn Falsedef ford_fulkerson(self, source, sink):parent = [-1] * self.rowmax_flow = 0while self.bfs(source, sink, parent):path_flow = float("Inf")s = sinkwhile s != source:path_flow = min(path_flow, self.graph[parent[s]][s]) s = parent[s]max_flow += path_flowv = sinkwhile v != source:u = parent[v]self.graph[u][v] -= path_flowself.graph[v][u] += path_flowv = parent[v]return max_flow# 测试用例graph = [[0, 16, 13, 0, 0, 0],[0, 0, 10, 12, 0, 0],[0, 4, 0, 0, 14, 0],[0, 0, 9, 0, 0, 20],[0, 0, 0, 7, 0, 4],[0, 0, 0, 0, 0, 0]]g = Graph(graph)source = 0sink = 5print("最大流量为:%d" % g.ford_fulkerson(source, sink)) ```上述代码首先定义了一个Graph类,其中包含了两个方法:bfs和ford_fulkerson。

ford-fullerson例题

ford-fullerson例题"Ford-Fulkerson算法"是计算机科学中用于解决网络流问题的一种算法,特别是在找到无向图或有向图的最大流方面。

该算法通过逐步增加流网络中的流量,直到达到最大流为止。

不过,你提到的"Ford-Fullerson"可能是个拼写错误,因为通常的术语是"Ford-Fulkerson"。

为了帮助你更好地理解,我会通过一个简化的例子来解释Ford-Fulkerson算法的基本概念。

例子:考虑一个有向图,其中有两个特殊的节点:源节点s和汇点t。

图中的每条边都有一个容量,表示可以通过该边的最大流量。

我们的目标是找到从s到t的最大流量。

步骤:1.初始化:开始时,所有边的流量都是0。

2.增广路径查找:找到一条从s到t的路径,该路径上的所有边的剩余容量(容量减去当前流量)都大于0。

这样的路径被称为增广路径。

3.增广:沿着找到的增广路径,尽可能多地增加流量,同时确保不超过任何边的容量。

增加的流量值等于增广路径上所有边剩余容量的最小值。

4.重复:重复步骤2和3,直到找不到更多的增广路径为止。

当找不到更多的增广路径时,我们就得到了从s到t的最大流。

注意:•Ford-Fulkerson算法的正确性依赖于选择的增广路径。

使用不同的增广路径可能会导致不同的流量分配,但最终得到的最大流总是相同的。

•如果所有边的容量都是有理数,Ford-Fulkerson算法保证会终止。

但是,如果边的容量是实数,该算法可能不会终止,除非使用特定的策略来选择增广路径(例如,使用Edmonds-Karp算法,它总是选择包含最少边的增广路径,从而保证了多项式时间复杂度)。

希望这个例子能帮助你理解Ford-Fulkerson算法的基本概念!如果你有更具体的问题或需要进一步的澄清,请告诉我。

最大流算法小结

网络最大流的算法网络最大流的算法分类:一、Ford-Fulkerson增广路方法1、Ford-Fulkerson标号算法(最简单的实现)分别记录这一轮扩展过程中的每个点的前驱与到该节点的增广最大流量,从源点开始扩展,每次选择一个点(必须保证已经扩展到这个点),检查与它连接的所有边,并进行扩展,直到扩展到t。

2、最大容量增广路算法每次找一条容量最大的增广路来增广,找的过程类似Dijkstra,实现起来相当简单。

3、Edmonds-Karp,最短路增广算法的BFS实现每次找一条最短的增广路,BFS是一个可以很方便的实现思想。

4、距离标号算法最短路增广的O(n)寻找实现,使用距离函数d:d[t]=0;d<=d[j]+1若存在(i,j)∈E;只有路径上满足d=d[i+1]+1的增广路才为满足要求的,一开始我们初始化使标号恰好满足要求,之后不断更改标号使其可以使增广继续。

5、Dinic,分层思想对网络分层(按照距t的距离),保留相邻层之间的边,然后运用一次类似于距离标号的方法(其实质是DFS)进行增广。

二、预留与推进算法1、一般性算法随便找个点,要么将他的盈余推出去,要么对他进行重标记,直至无活跃点为止。

2、重标记与前移算法维护一个队列,对一个点不断进行推进与重标记操作,直至其盈余为0,若过程中他没有被重标记过,则可出列,否则加入队头,继续等待检查。

3、最高标号预留与推进算法记录d值,然后优先处理d值较高的,直至没有盈余。

网络最大流的算法实现一、Edmonds-Karp(EK)算法就是用广度优先搜索来实现Ford-Fulkerson方法中对增广路径的计算,时间复杂度为O(VE2),Shortest Augmenting Path (SAP) 是每次寻找最短增广路的一类算法,Edmonds - Karp 算法以及后来著名的Dinic 算法都属于此。

SAP 类算法可统一描述如下:Shortest Augmenting Path{ x <-- 0while 在残量网络Gx 中存在增广路s ~> t do{ 找一条最短的增广路径Pdelta <-- min{rij:(i,j) 属于P}沿P 增广delta 大小的流量更新残量网络Gx}return x}在无权边的有向图中寻找最短路,最简单的方法就是广度优先搜索(BFS),E-K 算法就直接来源于此。

最大流算法


问题1:奶牛的新年晚会
奶牛们要举办一次别开生面的新年晚会。每头奶牛会做 一些不同样式的食品(单位是盘)。到时候他们会把自己最 拿手的不超过k样食品各做一盘带到晚会,和其他奶牛一起 分享。但考虑到食品太多会浪费掉,他们给每种食品的总盘 数都规定了一个不一定相同的上限值。这让他们很伤脑筋, 究竟应该怎样做,才能让晚会上食品的总盘数尽量的多呢? 例如:有4头奶牛,每头奶牛最多可以带3盘食品。一 共有5种食品,它们的数量上限是2、2、2、2、3。奶牛1会 做食品1…4,奶牛2会做食品2…5,奶牛3会做食品1、2、4, 奶牛4会做食品1…3。那么最多可以带9盘食品到晚会上。 即奶牛1做食品2…4,奶牛2做食品3…5,奶奶3做食品1、2, 奶牛4做食品1。这样,4种食品各有2、2、2、2、1盘。
网络流初步
◆ 最大流算法
◆ 最小费用最大流
◆ 最大流最小割定理
网络流之一
最大流算法
实例:
有一自来水管道输送系统,起点是S,目标是T, 途中经过的管道都有一个最大的容量。
4 7 4 1S 6 2 4 6 3 3
4
t
2
8 5
• 问题:问从S到T的最大水流量是多少?
4 7 1S 6
3 2
3 4 4
2 2-1=1
3
4
2
5
2
4
3
2 1
1
6
2 1
2
4
5
2 1
4、一条增广路径:
13 5
d=min{6-1,4-2} =2
2 2-1=1
3
4
2 2 1
5
增加流量: 2
Sum=5+2=7
2
4
3

贝尔曼-福特算法

贝尔曼-福特算法
贝尔曼-福特(Ford-Fulkerson)算法是最大流问题的求解算法,是流网络的核心。


算法是由两个著名的数学家,德国的L.R.Ford Jr.和美国的D.R.Fulkerson在1956年合
著的《Maximal Flow》一书中提出的,它使用贪心算法及回溯算法等来解决最大流问题。

贝尔曼-福特算法可以被用来求解一个来自于联结一个源顶点和一个汇顶点的网络中,最大流量。

在一个给定的网络上,即可通过贝尔曼-福特算法,找出从源顶点传输的最大
的可能的流量。

算法的运行步骤如下:
(1)首先,用任意可行流把源顶点与汇顶点连接起来;
(2)然后,从源顶点开始,舍弃原来的可行流,找出从源顶点出发的任一可正可负
残存容量边(如果所有边都被占满,那么此操作相当于退出);
(3)接着,将所有可正可负残存容量边的流量加减,使之可在有可能的情况下尽可
能接近最大流量状态;
(4)然后,从汇点的反方向来回搜索,当有任何一条可正可负残余容量的边可以被
找到时,将流量加减;
(5)最后,重复2~4的步骤,直到路径不能被找到,此时流量将被视为最大流量。

贝尔曼-福特算法比较简单,因此比较快,开销很低,且它是一个多重图算法,所以
可以求解任何复杂程度的流网络,比如:单源、单汇、双源双汇等,且不必花费多少时间
去修改算法。

而且,该算法也有一定的容错性,即便网络中的某些边被删除或增加,该算
法也能正常运行。

总而言之,贝尔曼-福特算法是一个快速有效的算法,因此在求解最大流问题中是比
较受重视的算法之一。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

对最大流算法Ford_Fulkerson的研究与理解自己学习《图论》的基础算法,终于走到最大流的地盘了呵呵……我可是足足整了三天啊!!!开始看ppt,讲述Ford_Fulkerson,尽管这个算法已经被更加优秀的Edmonds-Karp算法所取代。

我研究这个算法的目的其实在于Edmonds-Karp算法,没办法,谁叫Edmonds-Karp 算法是由Ford_Fulkerson改进过来的呢!把ppt看懂过后就自己上代码了。

结果真的是让人崩溃:有向图,流竟然可以回退!意味着有向图必须用无向图的思路来考虑!我自己写代码,优先考虑的是DFS。

因为我觉得既然是从起点到汇点。

DFS比较快嘛!我傻糊乎乎的照搬ppt上面的实现过程,把边提取出来,用一个类记录边的信息,然后用DFS 去搜索,边搜边改。

导致的结果是我连续改版了8次,一步步跟踪调试,当然注定是失败的!尽管最后都没成功,却让我一点一点清晰地理解了这个算法的实现过程!最后决定研究别人的代码了,不管三七二十一,先把代码贴出来吧!希望不会有盗用代码之嫌!1.package com.xh.Ford_Fulkerson;2.3.import java.util.LinkedList;4.import java.util.Queue;5.import java.util.Scanner;6.7./*8. * 6 10 // 6 nodes, 10 edges9. 0 1 16 // capacity from 0 to 1 is 1610. 0 2 13 // capacity from 0 to 2 is 1311. 1 2 10 // capacity from 1 to 2 is 1012. 2 1 4 // capacity from 2 to 1 is 413. 3 2 9 // capacity from 3 to 2 is 914. 1 3 12 // capacity from 1 to 3 is 1215. 2 4 14 // capacity from 2 to 4 is 1416. 4 3 7 // capacity from 4 to 3 is 717. 3 5 20 // capacity from 3 to 5 is 2018. 4 5 4 // capacity from 4 to 5 is 419. */20.public class Ford_Fulkerson09 {21.22.private int capacity[][];23.private int flow[][];24.private boolean visited[];25.private int pre[];//通过pre记录了路径26.private int nodes;27.static int count=0;28.static int[][] map = { { 0, 2, 9, 3, 0 },// 三条边29. { 0, 0, 7, 0, 8 },// 两条边30. { 0, 6, 0, 4, 0 },// 两条边31. { 0, 0, 0, 0, 5 },// 一条边32. { 0, 0, 0, 0, 0 } //33. };34.35.public Ford_Fulkerson09(int[][] capacity, int nodes) {36.this.capacity = capacity;37.this.nodes = nodes;38.this.flow = new int[nodes][nodes];39.this.pre = new int[nodes];40.this.visited = new boolean[nodes];41. }42.43.public int maxFlow(int src, int des) {44.int maxFlow = 0;45.46.for (int i = 0; i < nodes; i++)47.for (int j = 0; j < nodes; j++)48. flow[i][j] = 0;49.50.while (true)// find a augment path51. {52.for (int i = 0; i < nodes; i++) {53. visited[i] = false;54. }55. pre[src] = -1;56.57.if (!BFS(src, des)) {// the BFS58. System.out.println("break::::"+count);59.break;60. }61.62./*63. * DFS(src,des);//DFS if(!visited[des]) break;64. */65.int increment = Integer.MAX_VALUE;66.67. System.out.println("path:" +(count++));68.for (int i = des; pre[i] >= src; i = pre[i]) {69.// find the min flow of the path70. increment = Math.min(increment, capacity[pre[i]][i]71. - flow[pre[i]][i]);72. System.out.print(i+",");73. }74. System.out.print(0+",");75. System.out.println();76.// update the flow77.//对记录的路径的处理从终点开始,到起点这里的处理是很巧的78.for (int i = des; pre[i] >= src; i = pre[i]) {79. flow[pre[i]][i] += increment;80. flow[i][pre[i]] -= increment;//由于需要考虑到退回边,所以这里需要减少81./*不能不惊叹于这种处理本来我们的流是没有考虑负值的82. * 而且的话,向前流的回退流需要两种不同的处理,而这里作者直接让回退流为负83. * 这样的话,在bfs访问的过程中就不需要考虑两个点边的方向,这样就可以当作无84. * 向图的来处理了*/85. }86.// increase the maxFow with the increment87. System.out.println("==============flow==================");88.for (int i = 0; i < flow.length; i++) {89.for (int j = 0; j < flow.length; j++) {90. System.out.print(flow[i][j]+" ");91. }92. System.out.println();93. }94. System.out.println("increment======="+increment+"============");95. maxFlow += increment;96. }97.98.return maxFlow;99. }100.101.private boolean BFS(int src, int des) {102. Queue<Integer> queue = new LinkedList<Integer>();103. queue.add(src);104. visited[src] = true;105. System.out.print(queue.peek()+",");106.while (!queue.isEmpty()) {107.int node = queue.poll();108.for (int i = 0; i < nodes; i++) {109.if (!visited[i] && (capacity[node][i] - flow[node][i ] > 0)) {// 只要满足条件的点都加进去,而不会考虑两个点的边是正向边还是回退边110./*111. * capacity[node][i] - flow[node][i] > 0112. * 如果刚开始,回退边的flow是0,capacity也是0,不会被选择113. * 但是回退边的flow会被设为负值,所以后来遇到回退边的时候,回退边就会被考虑进来了尽管capacity为0114. */115. queue.add(i);116. visited[i] = true;117. pre[i] = node;// record the augment path118. System.out.print(i+",");119. }120. }121. }122. System.out.println("======================pre"+count+"====== ==========");123.for (int i = 0; i < pre.length; i++) {124. System.out.print(pre[i]+",");125. }126. System.out.println();127.return visited[des];128. }129.130.public static void main(String[] args) {131.int nodes;132. nodes = map[0].length;133.int[][] capacity = new int[nodes][nodes];134.135.for (int i = 0; i < nodes; i++) {136.for (int j = 0; j < nodes; j++) {137.if (map[i][j] != 0) {138. capacity[i][j] = map[i][j];139. }140. }141. }142.143. Ford_Fulkerson09 maxFlow = new Ford_Fulkerson09(capacity, no des);144. System.out.println(maxFlow.maxFlow(0, nodes - 1));145. }146.}由于代码中加入了打印输出,所以显得有点乱。

相关文档
最新文档