最短路径——Floyd算法

背景:本文是在小甲鱼数据结构教学视频中的代码的基础上,添加详细注释而完成的。该段代码并不完整,仅摘录了核心算法部分,结合自己的思考,谈谈理解。

Floyd算法理解:

Floyd算法其实非常的直观和简洁,而且可以解算出从以图的任何一个顶点作为起点和终点的最短路径(相对于Dijkstar算法的优势),这也是它虽然在时间复杂度上不如Dijkstar算法,却依然广泛流行的原因。

D数组:保存任意两个顶点之间的路径权值和(不断优化 算法结束时即为最短路径权值和),其中D[v][w]表示v顶点到w顶点的路径权值和(若在算法运行过程中,则为当前优化过程中的最短路径权值和(非最终))

P数组:保存任意两个顶点之间的路径中转顶点(或前驱顶点),其中P[v][w]表示v顶点到w顶点要想取得更短的路径权值和,需要经过的中转顶点。

Floyd算法的核心思想:(结合下方代码一起理解)

1、D数组中保存着所有的两个顶点之间的路径权值和,算法中对于D数组进行遍历,假设遍历过程中某一次位于D数组中的D[v][w],即D数组中的这个元素表示的是,当期解算出来的从v顶点到w顶点的最短路径权值和。

2、对于这样的一个最短权值和进行判断:如果存在一个顶点k,使得从v顶点出发,先去k顶点,再去w顶点的路径权值和小于D数组中当前的v到w的路径权值和,则优化v到w的路径

3、路径优化的操作:由于判断得出v到w以k顶点作为中转,比原来的v到w路径权值和更小,故将中转方式的路径权值和写入D数组,作为优化后的v到w的最短路径权值和。同时,将P数组中的P[v][w]优化为k,也就是说以k作为v到达w的中转顶点。

代码如下:

typedef int Pathmatirx[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX];

void ShortestPath_Floyd(MGragh G,Pathmatirx *P,ShortPathTable *D)
{
	int v,w,k;
	
	/* 初始化D和P */
	for(v=0;v<G.numVertexes;v++)
	{
		for(w=0;w<G.numVertexes;w++)
		{
			(*D)[v][w] = G.matirx[v][w];
			(*P)[v][w] = w;
		}
	}
	
	/* floyd */
	for(k=0;k<G.numVertexes;k++)
	{
		for(v=0;v<G.numVertexes;v++)
		{
			for(w=0;w<G.numVertexes;w++)
			{
				/* 如果D数值中当前的从v顶点到w顶点的路程权值和 大于 从v先经过k再到达w的路程权值和 */
				if( (*D)[v][w] > (*D)[v][k] + (*D)[k][w] )
				{
					/* 修改D数组:修改路径权值和 */
					/* 用以k作为中转的路径的权值和替代原本的路径权值和 */
					(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
					/* 修改D数组:修改路径(即修改路径中经过的中转顶点) */
					/* 从v先去k */
					(*P)[v][w] = (*P)[v][k];
				}
			}
		}
	}
}

 

——cloud over sky

 ——2020/3/12

 

 

 

 

posted @ 2020-03-12 19:52  Yu_tiann  阅读(209)  评论(0编辑  收藏  举报