floyd算法模板,floyd算法过程图解,floyd算法实现思路及实例代码

floyd算法模板,floyd算法过程图解,floyd算法实现思路及实例代码

本文主要介绍floyd算法的实现思路和示例代码,有需要的朋友可以参考一下。

我们知道,Floyd算法是用来寻找最短路径的。Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度是O(n ^ 3)。

Floyd算法的基本思想是:从任意节点A到任意节点B的最短路径无非是两种可能,一种是直接从A到B,另一种是从A经过几个节点X到B,因此我们假设Dis(AB)是从节点A到节点B的最短路径距离,对于每个节点X,我们检查Dis(AX) Dis(XB) Dis(AB)是否成立。如果为真,证明从A到X到B的路径比直接从A到B的路径短,我们设Dis(AB)=Dis(AX) Dis(XB),这样

很简单吧?代码可能如下所示:

复制代码如下:for(int I=0;I节点数量;I){ for(int j=0;j节点的数量;j){ for(int k=0;k个节点的数量;k){ if(Dis[I][k]Dis[k][j]Dis[I][j]){//找到一条更短的路径Dis[I][j]=Dis[I][k]Dis[k][j];} } }}

但是这里要注意循环的嵌套顺序。如果我们检查最内层的所有节点X,那么结果将是不正确的。为什么?这是因为过早地确定了从I到J的最短路径,当后面有更短的路径时,就不再更新了。

让我们看一个例子。看下图:

图中的红色数字代表边的权重。如果我们检查最内层的所有节点X,那么对于A-B,我们只能找到一条路径,即A-B,路径距离为9。这显然是不正确的。最短的真实路径是A-D-C-B,路径距离是6。错误的原因是我们检查了最内层的所有节点X,导致过早地确定了从A到B的最短路径,在确定从A到B的最短路径时,Dis(AC)还没有计算出来。所以,我们需要把循环顺序改写如下:复制代码code如下:for(int k=0;k个节点的数量;k){ for(int I=0;I节点数量;I){ for(int j=0;j节点的数量;j){ if(Dis[I][k]Dis[k][j]Dis[I][j]){//找到一条更短的路径Dis[I][j]=Dis[I][k]Dis[k][j];} } }}

这样,对于每个节点X,我们将处理所有I到J,然后继续检查下一个节点。

那么接下来的问题是,我们如何找到最短路径?这里需要一个辅助数组路径。它是这样使用的:如果Path(AB)的值是P,则表示从节点A到节点B的最短路径是A-.-P-B .这样,假设我们要找A-B的最短路径,然后依次搜索,假设路径(AB)的值是P,然后搜索路径(AP),假设路径(AP)的值是L,然后搜索路径(AL),假设路径(AL)的值是A,那么搜索结束,最短路径是A-L-P-B

那么,如何填充Path的值呢?很简单,当我们发现Dis(AX) Dis(XB) Dis(AB)成立时,我们必须将最短路径改为a-.-x-.-b .此时Path(XB)的值已知,所以,Path(AB)=Path(XB)。

好了,基本介绍完了,接下来就该实施了。在这里,我们使用图和邻接矩阵:复制代码如下:# define finite 1000//MAX # define MAX _ VERTEX _ COUNT 20//////////////////////////////

结构图{ int arrArcs[MAX _ VERTEX _ COUNT][MAX _ VERTEX _ COUNT];//邻接矩阵int nVertexCountint nArcCount的顶点数;//边数};/////////////////////////////////////////////////////

void ReadGraphData(graph * _ pg graph){ STD:cout 请输入顶点数和边数:;STD:CIN _ pGraph-nvertex count;STD:CIN _ pGraph-narc count;

标准:cout请输入邻接矩阵数据* STD:end;for(int row=0);row _ pgraph-转换计数:列){ for(int col=0);S7-1200可编程控制器:col){ STD:CIN _ pgraph-arrar RCS[row][col];} }

接着,就是核心的佛洛依德算法:复制代码代码如下-请参阅Floyd(int _ arr dis[][max _ vertex _ count]、int _ arr path[][max _ vertex _ count]、int _ convtonxcount//先初始化S7-1200可编程控制器:S7-1200可编程控制器:(I){ for(int j=0);j _ convtonxcount(j){ _ arr path[I][j]=I;在这种情况下,您可以选择一个选项来执行此操作。在这种情况下,您可以选择一个选项来执行此操作。在这种情况下,您可以选择一个选项来执行此操作。在这种情况下,您可以选择一个选项来执行此操作。在这种情况下,您可以选择一个选项来执行此操作

for(int k=0);k _ convtonxcount(k){ for(int I=0);S7-1200可编程控制器:(I){ for(int j=0);j _ convtonxcount{ if(_ arr dis[I][k]_ arr dis[k][j]_ arr dis[I][j]){//找到更短路径[I][j]=_ arr dis[I][k]_ arr dis[k][j];

_ arr path[I][j]=_ arr path[k][j];} } } } } }好的,最后是输出结果数据代码:复制代码代码如下:查看打印结果(int _ arr dis[][max _ vertex _ count]、int _ arr path[][max _ vertex _ count]、int _ convtonxcount){ STD:cout origin-dest distance path STD:end;

for(int I=0);S7-1200可编程控制器:(I){ for(int j=0);j _ convtonxcount(j ) { if ( i)!=j//节点不是自身{ STD:cout i1 - J1 t t;如果(无穷大==_arrDis[i][j] ) //i - j不存在路径{标准:无限弯头 t t} else { STD:cout _ arr dis[I][j] t t;

//由于我们查询最短路径是从后往前插,因此我们把查询得到的节点//压入栈中,最后弹出以顺序输出结果。STD:stack int堆栈顶点;内部k=j;

来自{ k=_ arr path[I][k];堆叠顶点。推(k);}而(k!=I;我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊

堆栈顶点。top()1;stackVertices.pop():

有符号int nlngth=堆栈顶点。size();对于(无符号int nindex=0);nindex lnn thnindex){ STD:cout "-堆栈顶点。top()1;stackVertices.pop():}

标准:cout J1小时* endl } } } }好了,是时候测试了,我们用的图如下:

测试代码如下:复制代码代码如下:int main( void ){图形mygraphread图数据(my graph);我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊

int arr dis[最大顶点计数][最大顶点计数];int arr path[最大顶点计数][最大顶点计数];

//先初始化S7-1200可编程控制器:我是我的图表。convtonxcount(I){ for(int j=0);我的图表。nvertexcount(j){ arr dis[I][j]=my graph。arrar RCS[I][j];} }

弗洛伊德(arrDis,arrPath,mygraph。verntexcount);我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊

printResult( arrDis、arrPath、mygraph。verntexcount);我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊!我的天啊

系统("暂停");返回0;}

如图:

floyd算法模板,floyd算法过程图解,floyd算法实现思路及实例代码