网络流问题Flow Network以及Ford-Fulkerson算法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


现实背景

人们经常使用图来建模交通网络——这些网络的边携带某种流量,其结点充当“交换机”传送不同边缘之间的流量。设想一个高速公路系统:边是公路,结点是交接处;或者设想计算机网络,这里的边是可以携带数据包的链路,而结点是交换机;再比如一个流体网络,其中的边是输送液体的管道,结点是管道的连接处。这种类型的网络模型有几个成分:①边的容量(说明它们最多能承载多少);②源结点——产生流量;③终端结点,可以“吸收”流量;④最后是流量本身,它是通过边传输的。


一、问题引入



假设这是一个水流网络系统,想从s点将水输送到t点,有向边代表管道,其权值表示的含义是该管道的最大容量,水通过该管道的流量不能大于容量,否则管道会破裂,除了s和t以外结点称为中间结点,每一个中间结点都满足:流入该中间结点的流量等于流出的流量,中间结点只是转换的作用,没有存储的功能。问:从s到t能输送最多多少的水流量?



二、问题建模

1.Flow Networks

其流量就是一种抽象的实体:在源结点产生,通过边传输,并在终端结点被吸收,我们将这样一种Flow Networks建模为一个 有向图G=(V,E),具有如下特点:

  1. 边e上的非负数值ce代表的是容量
  2. V中只有一个源结点s
  3. V中只有一个终端结点t
  4. V中除了s和t的结点叫作中间结点。

我们对该Flow Networks进行了三点假设:

  1. s没有入边,t没有出边
  2. 每个结点都至少和一条边关联
  3. 所有的容量值都用整数来表示


2.Defining Flow

定义s-t flow为函数f:把每条边e映射到一个正实数,f(e)的值表示的是e这条边上实际承载的流量。一个f flow必须满足以下两个特性:

  1. 容量约束:对于E中的每一个e,有0<=f(e)<=ce
  2. 平衡约束:对于所有的中间结点有
    在这里插入图片描述
    前者代表所有进入结点v的流量,后者代表从v流出的所有流量

一条边上的流量不能超过其容量,一个flow f的值,表示为v(f),其含义是在源结点产生的流量:

在这里插入图片描述

三、算法引入

1. Naive Algorithm

这个算法是初步的算法,并不一定能找到最大流,只能是大多数情况下可以找到最大流,但是这种方法很好理解,并且后面的更优的算法都是以此为基础进行优化的,所以我们先介绍这种算法。
在该算法中,我们需要定义一个Residual Graph(余量图)来表示每条管道还能承载的流量 可以用公式理解:

Residual = Capacity - Flow

在这里插入图片描述
每条管道上的红色权值代表流量,黑色代表容量

知道了这些概念后就可以操作该算法了。第一步,在原始图上随便用什么遍历方法找到一条从s到t的augmenting path(简单路径)就可以了,假设我们找到了:s->v2->v4->t 这条路径;然后根据短板原理可以知道我们能输送的最大流量是2,如果是3,就会有水管破裂。
在这里插入图片描述
所以这条路径的流量最大只能为2,这三条管道对应的余量应该都减去2,就可以画出当前状态下的余量图:
在这里插入图片描述
此时有两条边的余量为0,说明这两条管道已经饱和了,不能承受更多的睡了,于是把余量为0的边删除:
在这里插入图片描述
这样我们就完成了第一轮循环。接下来也是同样的操作,再找出一条从s到t的简单路径,设定最大流量,算出余量,删去饱和边,直到找不出一条从s到t的简单路径。第二轮循环:
在这里插入图片描述

第三轮循环:
在这里插入图片描述

第四轮循环已经找不出一条从s到t的路径了,于是算法终止,得到了最终的余量图,用原始图减去余量图就能得到流量图。
在这里插入图片描述
根据之前对问题建的模型,可以只看从s流出的流量和就知道了该图的实际流量是5。这个图的最大流量实际上就是5,但是如果选的路径不是上面这样的顺序,比如:一开始找的路径是这样的,确定流量值为3后,得到这样的余量图,并且删除饱和边
在这里插入图片描述
第三次循环已经找不到路径了,但是此时图的流量是4,并不是最大流量5。所以这个算法并不能总是找到最优解。

2. Ford-Fulkerson Algorithm

naive algorithm的问题在于一旦选择了bad path后,不能修正,就像上面描述的那样,选到了阻塞流后,就不能找到最大流了。用简单的示意图来表示:
在这里插入图片描述
红色的表示是max flow=2 , 紫色的表示block flow=1

我们现在要介绍的Ford-Fulkerson Algorithm 就是在此基础上优化的,假如选到了阻塞流,依然可以修正。我们依然按照之前用naive algorithm算法失败案例的选边顺序来运行Ford-Fulkerson Algorithm。Ford-Fulkerson Algorithm依然保留了原始图,余量图的概念。

在这里插入图片描述
这三步和之前的naive algorithm都是一样的,关键在于之后的这一步,就是删除了饱和边之后,Ford-Fulkerson Algorithm增加了一步回流法:画出该流量通路的逆流边,即从t到s的流向。并且这些回流边在下一轮选择路径试仍然可以被选中。
在这里插入图片描述
在这里插入图片描述
出现这种情况的时候,我们可以通过Merge(合并)操作处理。

第三轮循环就是到了刚才naive algorithm失败的那轮循环,如果没有这些回流边,该算法也会失败。正是有了这些回流边,因此我们才可以继续选择路径。

第三轮循环: 选中 s-> v2 -> v4 -> v1 -> v3 -> t, 并且确定这天路径的流量为1
在这里插入图片描述
移除饱和边后,并添加反向路径,然后Merge相应的边,得到了这样的余量图:
在这里插入图片描述
此时,找不到从s到t的路径了,于是算法终止。根据建模时的要求,我们可以从流入源结点的流量判定该图的最大流量为5。
因此,我们就用Ford-Fulkerson Algorithm对先前的失败案例进行修正,并得到了正确答案。




四、最坏情况时间复杂度

1. Worst-Case Iteration Complexity

在这里插入图片描述
该原始图的MaxFlow为200,很容易观察出来,但是如果用Ford-Fulkerson Algorithm算法,可能会非常慢。 假设一开始选的路径是 s->v1->v2->t,确定流量值为1,然后删除饱和边,画出回流边,得到的余量图是右边的:
在这里插入图片描述
在这里插入图片描述
Proof:
由于容量的限制,我们知道在图G没有流量值可以超过MaxFlow,并且每一轮循环中,流量值至少增加1,value从0开始增长并且不超过MaxFlow。
每轮循环至少会让Flow Network 的流量增加1,∴ Iterations<= Amount of MaxFlow。
在这个例子中,每一轮循环仅增加1流量,所以,在最坏情况下
Iterations = Amount of MaxFlow

2. Worst-Case Time Complexity

Proof:
假设有向图G中有m条边,n个结点,并且所有的结点都至少有一条相邻边,
∴m >= n/2. ∴我们可以用O(m+n)=O(m)来简化界限值。
由上面的证明可以知道算法最多循环MaxFlow次,该算法还会产生回流边,
∴余量图中最多有2m条边,即:每条边都有一条回流边。
找到一条从源结点到终端结点的路径,我们可以用广度优先算法或者深度优先算法,时间复杂度为O(m+n)=O(m);假设该网络流的MaxFlow为f,

∴ the Worst-case Time Complexity is O(f*m)

五、Edmonds-Karp Algorithm

我们再对Ford-Fulkerson Algorithm的过程总结一下:

  1. 根据原始图建立余量图,并初始化边的余量
  2. 如果能找到从源点到结点的简单路径,则进入循环:
    a. 在余量图上寻找一条简单路径
    b. 根据短板原理,确定该路径上的瓶颈值x
    c. 更新余量图:更新边的余量并删除饱和边
    d. 增加回流边

时间复杂度:O(f*m) f是MaxFlow m代表边的数量

该算法的缺陷在于:其时间复杂度依赖于最大流量,∴说明Ford-Fulkerson Algorithm可能会很慢,因为现实中的MaxFlow会很大。
在此基础上,就有了Edmonds-Karp Algorithm,该算法不是一种新的算法,它只是Ford-Fulkerson Algorithm的一种特例。它们唯一的区别就在于2-a步:

Edmonds-Karp Algorithm是在余量图上找源点到终点的最短路径

即:将余量图看成无权图,或者说将每条边的权值看为1,寻找无权图中的最短路径。也就是说,在每一轮循环中,依然是O(m)的时间寻找最短路径,该算法证明了循环次数最多为m*n次,m是边的数量,n是结点数量,∴该算法不再依赖于MaxFlow,性能因此才提升了很多。

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Ford-Fulkerson算法是一种解决最大问题算法,它通过不断寻找增广路径来增加量,直到无法找到增广路径为止。在Matlab中,可以使用图论工具箱中的函数来实现Ford-Fulkerson算法,例如使用graph和maxflow函数。具体实现方法可以参考Matlab官方文档或相关教程。 ### 回答2: Ford-Fulkerson算法是求解最大问题的一种经典算法,用于确定一个网络中从源节点到汇节点的最大可行量。下面我将简要介绍如何使用Matlab实现Ford-Fulkerson算法。 首先,我们需要定义一个图结构来表示网络。可以使用邻接矩阵来表示有向图,其中矩阵元素表示边的容量。源节点可以用一个预先定义的节点索引表示,汇节点也可以用另一个预先定义的节点索引表示。 接下来,我们可以实现Ford-Fulkerson算法的关键步骤。算法的主要思想是在剩余网络上找到增广路径,并在这条路径上增加量,直到不能找到增广路径为止。 具体实现中可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来找到增广路径。在每一次搜索过程中,我们需要判断当前节点是否已经被访问过,并且是否还可以通过当前边增加量。 在找到增广路径后,我们可以计算出该路径上的最小容量(也称作瓶颈容量),并将该容量从剩余网络中减去。随后,我们将该容量添加到网络中,并继续寻找新的增广路径。 当无法找到增广路径时,算法结束并返回最大量值。最大量值等于从源节点发出的所有量之和。 综上所述,以上是在Matlab中实现Ford-Fulkerson算法的基本步骤。当然,具体实现中还需要考虑一些细节问题,并且可能需要调用一些Matlab内置的图算法函数来辅助实现。 ### 回答3: Ford-Fulkerson算法是用于求解最大问题的一种常见算法,适用于有向图。算法的基本思想是不断在剩余网络中寻找一条增广路径,然后更新量分布,直到无法找到增广路径为止。 在MATLAB中,可以使用图算法工具箱中的函数来实现Ford-Fulkerson算法。具体步骤如下: 1. 首先,需要创建一个有向图对象,并定义图中的节点和边。可以使用Graph对象来进行操作。 2. 然后,设置源节点和汇节点,即确定最大的起点和终点。 3. 接下来,需要定义图中各个边的初始容量。可以使用addedge函数来添加边,并设置其容量。 4. 之后,可以使用fordfulkerson函数来求解最大。该函数会返回一个最大值,同时也会更新图中各个边的量。 5. 最后,可以使用findedge函数来查找某条边的量。该函数需要指定边的起点和终点节点,返回对应边的量值。 需要注意的是,Ford-Fulkerson算法的复杂度较高,最坏情况下为O(f * m),其中f为最大值,m为边的数量。因此,在处理大规模图的情况下可能会面临一定的挑战。 以上是用MATLAB实现Ford-Fulkerson算法的简要过程。通过使用MATLAB的图算法工具箱,可以方便地对最大问题进行求解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值