单源最短路径之Bellman-Ford

来源:互联网 发布:淘宝信誉度怎么说 编辑:程序博客网 时间:2024/04/27 19:29
Bellman-Ford的使用范围

1、单源

2、有负权重

3、有向

Bellman-Ford算法的描述

最短路径估计值g(v):当前求得的源节点s到节点v最短距离

最短路径d(v):源节点s带节点v的最短路径距离

Bellman-Ford算法通过对所有的边进行松弛操作来渐渐地降低从源节点s到每个节点v的最短路径估计值g(v),直到g(v)=d(v)。

Bellman-Ford算法的模板

class Edge//表示边,u为边的起点,v为边的终点,w为边的权重{int u;int v;int w;}int n;//节点的总个数int m;//边的总条数int s;//源节点Edge e[];//e[i]:第i条边int d[];//d[i]:s到i的最短路径长度boolean bellman_ford(){d[s]=0;boolean flag=false;//*//对所有的边进行n-1次松弛for(int i=1;i<n;i++){flag=false;//**//对所有的边进行松弛for(int j=0;j<m;j++){int u=e[j].u;int v=e[j].v;int w=e[j].w;if(d[v]>d[u]+w){d[v]=d[u]+w;flag=true;}}if(!flag)//若flag为false说明本次没有对任何一条边进行松弛,那么以后的每一次都不会对任何一条边进行松弛,所以剩下的松弛操作也没必要了{break;}}//**////***//判断是否有负环for(int i=0;i<m;i++){ int u=e[i].u;int v=e[i].v;int w=e[i].w;if(d[v]>d[u]+w){return false;//有负环}}return true;//没有负环//***//}


收敛性质:对于某些节点u,v,如果s~u~v是一条最短路径,并且在对边(u,v)进行松弛前的任意时间有g[u]=d[u],则在之后的所有时间有g[v]=d[v]。

证明Bellman-Ford的正确性

1、证明若不存在负环,则对所有边进行n-1次松弛之后,对于所有从s可以到达的节点v,有g[v]=d[v]

证明:设p=(s,v1,v2,...,vk)为从源节点到vk之间的任意一条最短路径。根据收敛性质,在进行第一次松弛后,g[v1]=d[v1],在进行第二次松弛后,g[v2]=d[v2],。。。,在进行第k次松弛后,g[vk]=d[vk]。由于p最多包含n-1条边,所以经过n-1次松弛后,对于所有从s可以到达的节点v,有g[v]=d[v]。

2、证明对所有边进行n-1次松弛之后,若有某条边(u,v),使得g(v)>g(u)+w(u,v),则存在负环

证明:我们可以断言:若没有负环,则对于任意一条边(u,v),有g(v)<=g(u)+w(u,v)。由于该命题成立,则该命题的逆否命题也成立。

所以可以推出:若有某条边使得g(v)>g(u)+w(u,v),则存在负环。得证

3、证明对所有边进行n-1次松弛之后,若对任意的边(u,v),都有g(v)<=g(u)+w(u,v),则不存在负环

证明:假设存在负环,设该环路为c=(v0,v1,v2,...,vk),v0=vk。

由于c未负环,所以有w(v0,v1)+w(v1,v2)+...+w(vk-1,vk)<0。

由于对于所有的边都有g(v)<=g(u)+w(u,v),

所以有g(vi)<=g(vi-1)+w(vi-1,vi),i=1,2,...,k,

将k个等式加起来,有g(v1)+g(v2)+...+g(vk)<=g(v0)+g(v1)+...+g(vk-1)+w(v0,v1)+w(v1,v2)+...+w(vk-1,vk),

由于v0=vk,

所以有g(v0)=g(vk)

所以有w(v0,v1)+w(v1,v2)+...+w(vk-1,vk)>=0.

这与w(v0,v1)+w(v1,v2)+...+w(vk-1,vk)<0相矛盾。所以命题正确



0 0
原创粉丝点击