最短路径(Dijkstra)算法

xiaoxiao2021-02-28  205

一、算法功能:

给定一个出发点(单源点)和一个有向网G=(V, E), 求出源点到其它各顶点之间的最短路径。


二、算法思想:

(1)把图中顶点集合分成两组,第一组为集合S,存放已求出其最短路径的顶点,第二组为尚未确定最短路径的顶点集合是V-S(令W=V-S),其中V为网中所有顶点集合。

(2)按最短路径长度递增的顺序逐个把W中的顶点加到S中,直到S中包含全部顶点,而W为空。

(3)在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到W中任何顶点的最短路径长度。

(4)此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,W中的顶点的距离从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。


三、实现步骤:

(1)初始时,S只包含源点,S={v},v的距离为0。U包含除v外的其他顶点,U中顶点的距离为顶点的权或∞ 。

(2)从U中选取一个距离最小的顶点k,把k加入到S中。

(3)以k 作为新考虑的中间点,**修改**U中各顶点的距离。

(4)重复步骤(1)、(2)直到所有顶点都包含在S中。


四、举例:

求v0到其它各点的最短路径:

答:最短路径为(V0,V2,V4,V3,V5)


五、算法实现:

/*====================================================== * Copyright (C) 2017 * * 文件名称:dijkstra.c * 创 建 者:ZhouYang * 创建日期:2017年06月01日 * 描 述:dijkstra算法实现 * ====================================================*/ #include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX_INT 32767 int main(void) { int i,j,k; int vertexLen, edgeLen; int len_S,len_U; int min,weight,sum=0; char initial_node,final_node; char node,mid; char startVertex, endVertex; printf("please input vertex's number:"); scanf("%d",&vertexLen); printf("please input edge's number:"); scanf("%d",&edgeLen); int graph[vertexLen][vertexLen]; char route[vertexLen]; char S[vertexLen],U[vertexLen]; int node_min[vertexLen]; for(i=0;i<vertexLen;i++) for(j=0;j<vertexLen;j++){ if(i==j) graph[i][j] = 0; else graph[i][j] = MAX_INT; } for(i=0; i<edgeLen; i++){ printf("please input the %d edge's start vertex name (vertex name from a to %c):",i+1,'a'+vertexLen-1); scanf(" %c",&startVertex); printf("please input the %d edge's end vertex name (vertex name from a to %c):",i+1,'a'+vertexLen-1); scanf(" %c",&endVertex); printf("please input this edge's weight:"); scanf("%d",&weight); graph[startVertex-'a'][endVertex-'a'] = weight; } for(i=0;i<vertexLen;i++) node_min[i]=MAX_INT; printf("Input initial node:"); scanf(" %c",&initial_node); printf("Input final node:"); scanf(" %c",&final_node); S[0]=initial_node; j=0; for(i=0;i<vertexLen;i++) { if(initial_node != 'a'+i) U[j++]='a'+i; } len_S=1; len_U=4; node_min[initial_node-'a']=0; node=initial_node; for(i=0;i<vertexLen-1;i++) { for(j=0;j<vertexLen;j++) { if(node_min[j]>graph[node-'a'][j]+node_min[node-'a']) { node_min[j]=graph[node-'a'][j]+node_min[node-'a']; } } min=MAX_INT; for(j=0;j<len_U;j++) { if(min>node_min[U[j]-'a']) { min=node_min[U[j]-'a']; mid=U[j]; k=j; } } while(k<len_U) { U[k]=U[k+1]; k++; } len_U--; len_S++; S[len_S-1]=mid; node=mid; } mid=final_node; k=0; route[k++]=mid; while(1) { for(i=0;i<vertexLen;i++) { if(mid!='a'+i) { if(node_min[mid-'a']-node_min[i]==graph[i][mid-'a']) { sum += node_min[mid-'a']-node_min[i]; mid='a'+i; route[k++]=mid; break; } } } if(mid == initial_node) break; } for(i = k-1;i>0;i--) printf("%c-->",route[i]); printf("%c",final_node); printf("\nweight sum is %d",sum); return 0; }

图如下:

运行结果:

转载请注明原文地址: https://www.6miu.com/read-25141.html

最新回复(0)