有向图之某个源点到其余各顶点的最短路径

1 生活中的实际问题

我们经常会计算从一个城市到另一个城市的交通费用,或者途中所需要的时间。比如,a城市到c城市,中间要经过b城市,a到b的时间是10,b到c的时间是20,或者也可以经过其他城市到c城市,总时间是不一样的。而要计算出最短的时间,考虑到交通的有向性,就可以化为解决有向图中某个顶点到其他顶点的最短路径,时间就是边的权值。并称路径上的第一个顶点为源点,最后一个顶点为终点。

2 讨论两种最常见的最短路径问题之一——从某个源点到其余各顶点的最短路径

2.1 给定带权有向图G和源点a,求从a到G中其余各顶点的最短路径

如图:


如何求得这些路径?迪杰斯特拉(Dijkstra)提出了一个按路径长度递增的次序产生最短路径的算法。

2.2 算法思想

按路径长度递增次序产生算法

* 图的顶点的集合是V,已求得最短路径的终点的集合是S,V-S=T,T是尚未求出来最短路径的顶点集合

* 将T中顶点按次序加入到S中

(次序:就是源点到T中顶点的距离有大有小,按照从小到大的次序,源点到其他顶点有路径的距离值有具体值,没有路径的距离值是无限大)

3 c语言算法的实现

3.1 用带权的邻接矩阵arcs来表示带权有向图,arcs[i][j]表示弧<vi,vj>上的权值。若<vi,vj>不存在,则置arcs[i][j]为无限大(可以用允许的最大值替代)。S为已找到从源点出发的最短路径的终点的集合,它的初始状态为空集。那么,从源点出发到图上其余各顶点(终点)vi可能达到的最短路径长度的初始值为:

       D[i]=arcs[源点的位置][i]     vi属于V

3.2 选择vj,使得

     D[j]=Min{D[i] | vi属于V-S}  (意思是:在V-S的顶点集中,选择一个距离最短的顶点)

    vj就是当前求得的一条从v出发的最短路径的终点,令

     S=S U {j}

(其实就是假如 a顶点到f顶点距离是100,到c顶点距离是10,那就选择最小的距离,就是10,j就是顶点c;就是源点到其他顶点的距离集合中选择最小的一个,直至把到其他顶点的距离都算出来,把顶点加入到S中)

3.3 修改从源点出发到集合V-S上任一顶点vk可达的最短路径长度。如果

     D[j]+arcs[j][k]<D[k]

     则修改D[k]为 D[k]=D[j]+arcs[j][k]

(找到最短路径后为什么要修改从源点到其他顶点的最短路径长度?

  比如d顶点,初始的时候,a顶点并没有到d顶点的路径,所以其最短距离是无限大,但是按次序找到到c顶点,把c顶点添加到S集合后,a顶点就有路径到d顶点了,通过<a,c>,<c,d>弧就可以到达d,那么a到d的最短路径就需要更新一下,以备下一次寻找a顶点到V-S集合中的顶点的最短距离。一般情况下,假设S为已求得最短路径的终点的集合,则可证明:下一条最短路径(设其终点为X)或者是弧<v,x>,或者是中间只经过S中的顶点而最后到达顶点X的路径。其实就是假如一开始源点到一些顶点没有路径,而找到一个有最短路径的顶点的时候,有可能源点通过这个顶点可以到达之前没有路径的顶点;或者是之前到这些顶点有路径,但是通过这个顶点到这些顶点的路径比原来直接到这些顶点的路径短;这些情况都需要更新路径,以便下一次寻找源点到其他顶点的距离中选择最短路径时使用。

3.4 重复操作(2) (3)步骤,共n-1次,由此求得从源点到图上其余各顶点的最短路径是依路径长度递增的顺序.

3.5 得出的结果是

起点     终点          最短路径            路径长度

a         b               无                   

          c               (a,c)                   10

          d.              (a,e,d)                 50

          e               (a,e)                   30

          f               (a,e,d,f)               60

实现的源码:    [email protected]:hglspace/GraphShortesPath.git

猜你喜欢

转载自blog.csdn.net/weixin_37885641/article/details/79235332