网络最大流问题

 

2010-10-31   10:19:36

初学了一下网络流算法,站在前人的肩膀上,参考了不少资料,总结了一下学习经验:

准备知识:(参考资料)


1.Dijkstra算法

    适用于满足所有权系数大于等于0(lij≥0)的网络最短路问题,能求出起点v1到所有其他点vj的最短距离;

    朴素的Dijkstra算法复杂度为O(N^2),堆实现的Dijkstra复杂度为O(NlogN).

 

2.bellman-ford算法

    适用于有负权系数,但无负回路的有向或无向网络的最短路问题,能求出起点v1到所有其它点 vj的最短距离。bellman-ford算法复杂度为O(V*E)。

 

3.Floyed算法

    适用于有负权系数,可以求出图上任意两点之间的最短路径。DP思想的算法,时间复杂度为O(N^3);

  for ( k= 1; k<= n; k++)
  {
	  for ( i= 1; i<= n; i++)
	  {
		  if (graph[i][k]!=INF)
		  {
			  for ( j= 1; j<= n; j++)
			  {
				  if (graph[k][j]!=INF && graph[i][k]+graph[k][j]< graph[i][j])
					  graph[i][j]= graph[i][k]+ graph[k][j]; 
			  }
	  }
  } 

                                               s-t最大流

 两大类算法

 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(e1),s(e2),…,s(ek)} 

         STEP4:对于增广路中的前向弧,令f(e)=f(e)+crement;对于其中的反向弧,令f(e)=f(e)-crement,转STEP1。

  关键点:寻找可增广路。决定了算法复杂度。

  实现:Edmonds-Karp  通过采用了广度优先的搜索策略得以使其复杂度达到O(V*E^2)。 

 

  优化—> Dinic算法(*)

  Dinic算法的思想是为了减少增广次数,建立一个辅助网络L,L与原网络G具有相同的节点数,但边上的容量有所不同,在L上进行增广,将增广后的流值回写到原网络上,再建立当前网络的辅助网络,如此反复,达到最大流。分层的目的是降低寻找增广路的代价。

  算法的时间复杂度为O(V^2*E)。其中m为弧的数目,是多项式算法。邻接表表示图,空间复杂度为O(V+E)。

 

 2.预流推进算法  

  一般性的push-relabel算法: 时间复杂度达到O(V^2*E)。(*) 

  relabel-to-front算法->改进 

  最高标号预流推进:时间复杂度O(V^2*sqrt(E))


相关参考资料链接(详细图解):http://wenku.baidu.com/view/157cf76c1eb91a37f1115c3a.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值