Just enjoy programming

最短路径

(一)迪杰斯特拉算法(时间复杂度O(n2))
       迪杰斯特拉(Dijkstra)算法是求某个源点到其余各顶点的最短路径,这是一个按路径长度递增的次序产生最短路径的算法。
       首先引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点vi的最短路径的长度。它的初态为:若从v到vi有弧,则D[i]为弧上的权值;否则置D[i]为无穷大。显然,长度为D[j]=Min{D[i]|vi属于V}的路径就是从v出发的长度最短的一条最短路径。因此,在一般情况下,下一条长度次短的最短路径的长度必为D[j]=Min{D[i]|vi 属于 V-S} 其中D[i]或者为弧(v,vi)上的权值,或者是D[k](vk属于S)和弧(vk,vi)上的权值之和。算法步骤如下:
(1)假设用带权的邻接矩阵arcs来表示带权有向图,arcs[i][j]表示弧(vi,vj)上的权值。若(vi,vj)不存在,则置arcs[i][j]为无穷大。S为已找到从v出发的最短路径的终点的集合,它的初始状态为空集。那么,从v出发到图上其余各顶点(终点)vi,可能达到的最短路径长度的初值为:
D[i]=G.arcs[v][vi],vi属于V
(2)选择Vj,使得
   D[j]=Min{D[i]|vi 属于V-S}
vj 就是当前求得的一条从v出发的最短路径的终点。令
   S=SU {j}
(3)   修改从v出发到集合V-S上任一顶点vk可达的最短路径长度。如果D[j]+arcs[j][k]<D[k]则修改D[k]为 D[k]=D[j]+arcs[j][k]
(4) 重复操作(2),(3)共 n-1次。由此求得从v到图上其余各顶点的最短路径是依路径长度递增的序列。

(二)弗洛伊德(Floyd)算法(时间复杂度为O(n3))
弗洛伊德(Floyd)算法是求图中每一对顶点之间的最短路径,时间复杂度为O(n3).
弗洛伊德算法仍从图的带权邻接矩阵cost出发,其基本思想是 :
假设求从顶点vi到vj的最短路径。如果从vi到vj有弧,则从vi到vj存在一条长度arcs[i][j]的路径,该路径不一定是最短路径,尚需进行n次试探。首先考虑路径(vi,v0,vj)是否存在(即判别弧(vi,v0)和(v0,vj)是否存在)。 如果存在,则比较(vi,vj)和(vi,v0,vj)是否存在(即判别弧(vi,v0)和(v0,vj)是否存在).如果存在,则比较(vi,vj)和(vi,v0,vj)的路径长度取长度较短者为从vi到vj的中间顶点的序号不大于0的最短路径。假如在路径上再增加一个顶点v1,也就是说,如果(vi,...v1)和(v1...vj)分别为当前找到的中间顶点的序号不大于0的最短路径,那么(vi,...,v1,...vj)就有可能是从vi到vj的中间顶点的序号不大于1的最短路径。将它和已经得到的从vi到vj中间的顶点序号不大于0的最短路径相比较,从中选出中间顶点的序号不大于1的最短路径之后,再增加一个顶点v2,继续进行试探。依次类推。在一般情况下,若(vi,...,vk)和(vk,...vj)分别是从vi到vk和从vk到vj的中间顶点的序号不大于k-1的最短路径,则将(vi,...vk,...vj)和已经得到的从vi到vj且中间顶点序号不大于k-1的最短路径相比较,其长度较短者便是从vi到vj的中间顶点的序号不大于k的最短路径。这样,在经过n次比较后,最后求得的必是从vi到vj的最短路径。
现定义一个n阶方阵序列
D(-1),D(0),D(1),...D(k),...D(n-1)
其中
D(-1)[i][j]=G.arcs[i][j].
D(k)[i][j]=Min{D(k-1)[i][j],D(k-1)[i][k]+D(k-1)[k][j]}  0<=k<=n-1
从上述计算公式可见,D(1)[i][j]是从vi到vj的中间顶点的序号不大于1的最短路径的长度。D(k)[i][j]是从vi到vj的中间顶点的序号不大于k的最短路径的长度。D(n-1)[i][j]就是从vi到vj的最短路径的长度。

posted on 2011-05-19 16:44 周强 阅读(481) 评论(2)  编辑 收藏 引用 所属分类: 算法

评论

# re: 最短路径 2011-05-25 20:48 十三

好熟的名字~
俺好像学过~~  回复  更多评论   

# re: 最短路径 2011-05-25 23:20 周强

@十三
恩,经典两个算法  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理