图的最短路径(Dijkstra方法和Floyed方法)

什么是最短路径?

1、在非网图中,两顶点之间经过顶点最少的路径,就是最短路径。
2、在网图中,两点之间经过的权值之和最小的路经。

最短路径问题的解决方法

Dijkstra方法(单源点到其他顶点的最短路径)

Floyed方法 (任意两点之间的最短路径)

1.Dijkstra方法

算法思想
1.设置一个集合S存放已经找到最短路径的顶点,初始值为单源点(起始点)。
2.以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与原来的假设相比较,取路径长度较小者为最短路径。
3.重复操作,直到V全部顶点加入到S中。

数据结构设计:
1、图的存储结构:邻接矩阵存储结构
2、数组dist[n]:每个分量dist[i]表示当前所找到的从始点v到终点vi的最短路径的长 度。初态为:若从v到vi有弧,则dist[i]为弧上权值;否则置dist[i]为∞。
3、数组path[n]:path[i]是一个字符串,表示当前所找到的从始点v到终点vi的最短路径。初态为:若从v到vi有弧,则path[i]为vvi;否则置path[i]空串。
4、数组s[n]:存放源点和已经找到最短路径的终点,其初态为只有一个源点v。

伪代码
1、S←{v0} , dist[i]= g.arc[v0][vi] , path[i]=“v0vi ” 或 “ ”;
将v0到其余顶点的路径长度初始化为权值;
2、选择vk,使得dist[vk]=min(dist[i] | vi∈V-S)
vk为目前求得的下一条从v0出发的最短路径的终点。
将vk加入到S中。
3、修改从v0出发到集合V-S上任一顶点vi的最短路径的长度。
如果
dist[k]+ g.arck][i]<dist[i]
则将dist[i]修改为
dist[k]+ g.arc[k][i]
path[i]=path[k]+”vi”
4、重复(2)、(3) n-1次,即可按最短路径长度的递增顺序,逐个求出v0到图中其它每个顶点的最短路径。

const int MAX=1000;
void  Dijkstra(MGraph g, int v){
       for ( i =0; i<g.vexnum ; i++){
	 dist[i]=g.arcs[v][i];  
               if ( dist[i]!= MAX) 
                      path [i]=g.vertex[v]+g.vertex[i];
               else
                      path[i]=“”;
       }
       S[0]=g.vertex[v]; 
       num=1;  
       While (num<g.vextexNum){
    k=0;
    for(i=0;i<G.vertexNum;i++)
           if((dist[i]<dist[k])   k=i
    cout<<dist[k]<<path[k];
    s[num++]=G.vertex[k];                
    for(i=0;i<G.vertexNum;i++)
             if(dist[k]+g.arc[k][i]<dist[i] {
		 dist[i]=dist[k]+g.arc[k][i];
                       path[i]=path[k]+g.vertex[i];
               }
}
}

2.Floyed方法

算法思想:
设图g用邻接矩阵法表示,
求图g中任意一对顶点vi、 vj间的最短路径。

(-1) 将vi到vj 的最短的路径长度初始化为(vi,vj), 然后进行如下n次比较和修正:
(0) 在vi、vj间加入顶点v0,
比较(vi, v0, vj)和(vi, vj)的路径的长度,取其中较短的路径作为vi到vj的且中间顶点号不大于0的最短路径。

(1)在vi、vj间加入顶点v1:
得(vi, …,v1)和(v1, …,vj),其中:
(vi, …, v1)是vi到v1 的且中间顶点号不大于0的最短路径,
(v1, …, vj) 是v1到vj 的且中间顶点号不大于0的最短路径,
这两条路径在上一步中已求出。
将(vi, …, v1, …, vj)与上一步已求出的且vi到vj 中间顶点号不大于0的最短路径比较,取其中较短的路径作为vi到vj 的且中间顶点号不大于1的最短路径。

重复操作n次…

数据结构设计:
图的存储结构:带权的邻接矩阵存储结构
数组dist[n][n]:存放在迭代过程中求得的最短路径长度。
数组path[n][n]: 存放从vi到vj的最短路径,初始为path[i][j]=“vivj”。

void Floyd(MGraph G)
{
    for (i=0; i<G.vertexNum; i++)        
       for (j=0; j<G.vertexNum; j++)
       {
          dist[i][j]=G.arc[i][j];
          if (dist[i][j]!=) 
               path[i][j]=G.vertex[i]+G.vertex[j];
          else path[i][j]=""; 
       }
            for (k=0; k<G.vertexNum; k++)         
        for (i=0; i<G.vertexNum; i++)       
           for (j=0; j<G.vertexNum; j++)
               if (dist[i][k]+dist[k][j]<dist[i][j]) {
                    dist[i][j]=dist[i][k]+dist[k][j];
                    path[i][j]=path[i][k]+path[k][j];
              }
}
发布了36 篇原创文章 · 获赞 3 · 访问量 3531

猜你喜欢

转载自blog.csdn.net/qq_43628835/article/details/103354600