最短路径——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