最短路径

从某个源点到其余各顶点的最短路径

先讨论单源点的最短路径问题:给定带权有向图G和源点v,求从v到G中其余各顶点的最短路径。

Dijkstra算法:按路径长度递增的次序产生最短路径的算法。
首先,引进一个辅助常量D。它的每个分量D[ i ]表示当前所找到的从始点v到每个终点vi的最短路径的长度。它的初态为:若从v到vi有弧,则D[ i ] 为弧上的权值;否则置D为∞。显然,长度为 D[ j ] = Min{ D[ i ] | vi ∈ V} 的路径
就是从c出发的长度最短的一条最短路径。此路径为( v,vj)。
在一般情况下,下一条长度次短的最短路径的长度必是 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 ] = arcs[ Locate Vex(G, v)[ i ] vi∈V
(2)选择vj,使得D[ j ] = Min{D[ i ] | vi ∈ V-S}
vj就是当前求得的一条从v出发的最短路径的终点。令S = S ∪ { 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到涂上其余各顶点的最短路径是以路径长度递增的序列。

void ShortesPath_DIJ(MGraph G, int v0, PathMatrix &P, ShortPathTable &D){
    for (v = 0; v < G/vexnum; ++v){
        final[v] = FALSE; D[v] = G.arcs[v0][v];
        for(w = 0; w < g.vexnum; ++w)
            P[v][w] = FALSE;
        if(D[v] < INFINITY){
            P[v][v0] = TRUE;
            P[v][v] = TRUE;
        }
    }
    D[v0] = -;
    final[v0] = TRUE;
    for(i = 1; i < G.vexnum ; ++i){
        min = INFINITY;
        for(w=0; w < G.vexnum; ++w)
            if(!final[w])
                if(D[w] < min){
                    v = w;
                    min = D[w];
                }
        for(w = 0; w < g.vexnum; ++w)
            if(!final[w]&&(min + G.arcs[v][w] < D[w])){
                D[w] = min + G.arcs[v][w];
                P[w] = P[v];
                p[w][w] = TRUE;
            }
    }
}

Floyd算法
通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入两个矩阵,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。矩阵P中的元素b[i][j],表示顶点i到顶点j经过了b[i][j]记录的值所表示的顶点。

假设图G中顶点个数为N,则需要对矩阵D和矩阵P进行N次更新。初始时,矩阵D中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞,矩阵P的值为顶点b[i][j]的j的值。 接下来开始,对矩阵D进行N次更新。第1次更新时,如果”a[i][j]的距离” > “a[i][0]+a[0][j]”(a[i][0]+a[0][j]表示”i与j之间经过第1个顶点的距离”),则更新a[i][j]为”a[i][0]+a[0][j]”,更新b[i][j]=b[i][0]。 同理,第k次更新时,如果”a[i][j]的距离” > “a[i][k-1]+a[k-1][j]”,则更新a[i][j]为”a[i][k-1]+a[k-1][j]”,b[i][j]=b[i][k-1]。更新N次。

void ShortesPath_FLOYD( MGraph G, PathMatrix &P[ ], DistancMatrix &D )
{
    for(v = 0; v < G.vexnum; ++v)
        for(w = 0; w < G.vexnum; ++w){
            D[v][w] = G.arcs[v][w];
            for(u = 0; u < G.vexnum; ++u)
                P[v][w][u] = FALSE;
            if(D[v][w] < INFINITY){
                P[v][w][v] = TRUE;
                P[v][w][w] = TRUE;
            }
        }
    for(u = 0; u < G.vexnum; ++u)
        for( v = 0; v < G.vexnum; ++w)
            if(D[v][u] + D[u][w] < D[v][w]){
                D[v][w] = D[v][u] + D[u][w];
                for(i = 0; i < G.vexnum; ++i)
                    P[v][w][i] = P[v][u][i] || P[u][w][i];
            }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值