文章目录
- 最短路径:最短路径是指从图(网)中某一顶点,到其余各顶点的最短路径。
- 最短路径与最小生成树主要有三点不同:
- 最短路径操作对象是有向图(网),而最小生成树的操作对象是无向图(网)。
- 最短路径有一个明确的始点,而最小生成树没有。
- 最短路径关注的是始点到每个顶点的路径最短,而最小生成树关心的是整个支撑树的代价最小。
Dijkstra算法
从图的给定源点到其他各个顶点之间客观上应存在一条最短路径,在这组最短路径中,按其长度的递增次序,依次生成从源点到不同顶点的最短路径。
Dijkstra算法基于以下事实:
D
[
i
]
=
{
<
源
点
到
顶
点
i
的
弧
上
的
权
值
>
<
源
点
到
其
他
顶
点
(
其
与
源
点
的
最
短
路
径
已
求
出
)
的
路
径
权
值
>
+
<
其
他
顶
点
到
顶
点
i
的
弧
上
的
权
值
>
D[i]=\begin{cases} <源点到顶点i的弧上的权值>\\ <源点到其他顶点(其与源点的最短路径已求出)的路径权值>+<其他顶点到顶点i的弧上的权值>\\ \end{cases}
D[i]={<源点到顶点i的弧上的权值><源点到其他顶点(其与源点的最短路径已求出)的路径权值>+<其他顶点到顶点i的弧上的权值>
故每求得一个顶点的最短路径,必能得到到另一个顶点的最短路径
实现细节:
- 引进一个辅助向量 D D D,每个分量 D [ i ] D[i] D[i]表示当前所找到的从始点到每个终点 v i v_i vi的最短路径长度
- D [ i ] D[i] D[i]初值为始点 v 0 v_0 v0到各终点 v i v_i vi的直接距离,即若始点到某顶点有弧,则为弧上的权值,否则为 ∞ ∞ ∞
实现:
void ShortestPath(char StartVexChar,int Dest[],char Path[][MAXVERTEXNUM]){ //StartVexChar为始点,Dest存储权值
int m,StartVex,CurrentVex,MinDest;
int S[MAXVERTEXNUM]; //标记某顶点是否已找到最短路径
for(int i=0;i<VertexNum;i++){ //找到始点的嘘号
if(Vertex[i]==StartVexChar){
StartVex = i;
Path[StartVex][0]='\0';
break;
}
}
for(int i=0;i<VertexNum;i++){ //初始化
if(i!=StartVex){
Dest[i] = INFINITY; //所有顶点到始点之间的距离初值设为无穷大
if(AdjMatrix[StartVex][i]<INFINITY){ //始点与当前顶点之间存在弧
Dest[i]=AdjMatrix[StartVex][i]; //初始化权值为始点到当前顶点弧的权值
Path[i][0]=Vertex[StartVex]; //路径的第一个点为始点
Path[i][1]=Vertex[i]; //第二个点为当前顶点
Path[i][2]='\0'; //最后一个字符为空字符
}
S[i] = 'F'; //标记当前顶点未找到最短路径
}
}
Dest[StartVex] = 0; //始点的路径权值未0
S[StartVex] = 'T'; //始点已找到最短路径
for(int i=0;i<VertexNum;i++){ //具体实现
MinDest=INFINITY;
for(int j=0;j<VertexNum;j++){ //找到上一轮迭代中后所有路径中的最短路径,此最短路径必为到某顶点的最短路径
if(S[j]=='F'){
if(Dest[j]<MinDest){
CurrentVex = j;
MinDest = Dest[j];
}
}
}
S[CurrentVex] = 'T';
for(int j=0;j<VertexNum;j++){
if((S[j]=='F')&&(MinDest+AdjMatrix[CurrentVex][j]<Dest[j])){
Dest[j]=MinDest+AdjMatrix[CurrentVex][j]; //使用新找到的最短路径来更新其余点的最短路径
for(int m=0;Path[CurrentVex][m]!='\0';m++){ //若某顶点的最短路径被更新,则更新该顶点到开始顶点的路径
Path[j][m] = Path[CurrentVex][m];
}
Path[j][m++] = Vertex[j];
Path[j][m]='\0'
}
}
}
}