网络流算法介绍

文章介绍了网络流算法在网络规划、献血分配等问题中的应用,特别讲解了Ford-Fulkerson方法来寻找最大流量。通过实例展示了如何构建ResidualGraph并利用它来扩大流,从而找到最大流量。此外,提及了加速算法的可能性和ResidualGraph中忘记反向箭头的影响。
摘要由CSDN通过智能技术生成

网络流(network flow)算法是一个又实用又有趣又重要还老少皆宜的算法。而且还可以用在实际生活中。

比如说,现在有105个血包(50个O型,36个A型,11个B型,8个AB型),分给100个伤员(45个O型,42个A型,10个B型,3个AB型)可能吗?

注:O型是万能输血者,AB型是万能接收者。除此之外,A型能输A型,B型能输B型。

 

转化为网络流问题:在上图中能不能有100单位的水从s流到t?(上图所有箭头从左往右)其中除了s和t之外的节点都不能提供、储藏、吸收水!

答案是不能。这张图最多只能流过99单位。有一个伤员得不到血袋了。

 

从蓝圈内到蓝圈外最多只能流99个单位!所以从s到t最多只能流99个单位!

那么怎么才能找到这个圈呢?

 

先随便在s注入一些水,形成了一个流。上图中已经放了45+36+10+3=94个单位的水了。

当一个流出现以后,同时会出现这个流的Residual Graph。所谓Residual Graph,就是把流从原图中线的容量减去,再添加一条和流反向的路径。注:没标数字的线容量是正无穷,正无穷减掉了流在这条线上的流量后,还是正无穷。

 

一个流的Residual Graph可以指导我们怎么扩大这个流的流量。

 

照着这条道路,给流再注入一些水。

 

得到了一个新流。当流产生的时候,流的Residual Graph也同时产生了。

随便弄个流-流诞生后,流的Residual Graph同时诞生-在Residual Graph中寻找s-t通路-找到了就利用该通路扩大流,产生新流,产生新流的Residual Graph......找不到就结束算法,大功告成。

 

这样,我们不仅找到了这幅图里的最大流量,还找到了开头的那个圈!

 

以上就是网络流的Ford-Fulkerson方法。时间复杂度O(mC)。m为边数,C为流量的最大可能值。

有一些技巧似乎可以加速该方法,比如给每个节点赋一个值,创造一个等价问题,使得Residual Graph中所有边非负,然后内嵌Dijkstra最短路算法。这样可以加速到O(mlogn)n为点数量。然而我看了三遍也没想清楚一些具体细节,以后用到了再说吧了。

还有一个挺有意思的问题。就是如果你在画Residual Graph的时候忘记画反向箭头了会怎样?显然会得到一个错误答案。但这个错误答案会不会总是大于等于正确答案乘以一个常数呢?我觉得答案是0.5,毕竟你没有利用到的流的Residual Graph中的反向边最多和这个流的流量相等。又可以找到例子使它恰好是0.5。

不仅是用在献血上,这个小小的算法还能用在飞机规划、图像前景背景分离、调节供需上。

本文参考了Jon Kleinberg和Eva Tardos的Algorithm Design。图片均由本文作者绘制。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值