图的最短路径(Dijkstra算法)

文章目录

  • 最短路径:最短路径是指从图(网)中某一顶点,到其余各顶点的最短路径。

  • 最短路径与最小生成树主要有三点不同:
    1. 最短路径操作对象是有向图(网),而最小生成树的操作对象是无向图(网)。
    2. 最短路径有一个明确的始点,而最小生成树没有。
    3. 最短路径关注的是始点到每个顶点的路径最短,而最小生成树关心的是整个支撑树的代价最小。

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'
			}
		}
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值