关于Floyd算法,path数组一定能保存正确的路径吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Floyd算法,path数组一定能保存正确的路径吗?相关的知识,希望对你有一定的参考价值。

数据结构里的弗洛伊德算法,我怎么觉得这个path数组不一定能保存正确的路径?因为我想:它初始化全为-1(不能到达);如果算法运行过程中没有对它进行过修改,就认为不能到达了,但事实可以是可以到达的啊???这是中国大学数据结构课程的源码:(我试过输出path数组有为-1的····怎么理解?怎么办)/* 邻接矩阵存储 - 多源最短路算法 */ bool Floyd( MGraph Graph, WeightType D[][MaxVertexNum], Vertex path[][MaxVertexNum] ) Vertex i, j, k; /* 初始化 */ for ( i=0; i<Graph->Nv; i++ ) for( j=0; j<Graph->Nv; j++ ) D[i][j] = Graph->G[i][j]; path[i][j] = -1; for( k=0; k<Graph->Nv; k++ ) for( i=0; i<Graph->Nv; i++ ) for( j=0; j<Graph->Nv; j++ ) if( D[i][k] + D[k][j] < D[i][j] ) D[i][j] = D[i][k] + D[k][j]; if ( i==j && D[i][j]<0 ) /* 若发现负值圈 */ return false; /* 不能正确解决,返回错误标记 */ path[i][j] = k; return true; /* 算法执行完毕,返回正确标记 */

能的

可以看下这段代码

for(k=1;k<=n;k++)
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]),path[i][j]=path[i][k];

然后可以模拟一下

path是可以存下来的

参考技术A 你说的是浙大的mooc数据结构,我也看了,她漏了path的一步初始化,即如果存在直接边的情况下(D[i][j]<INFINITY),是需要把path[i][j]初始化为i的。
因为如果i和j直接边是它们的最短路径,
if (Dist[i][k] + Dist[k][j] < Dist[i][j])
Dist[i][j] = Dist[i][k] + Dist[k][j];
Path[i][j] = k;

是不会更新path的,这样直接边作为最短路径的path会为-1.

Floyd(动态规划)求解任意两点间的最短路径(图解)

Floyd算法的精髓在于动态规划的思想,即每次找最优解时都建立在上一次最优解的基础上,当算法执行完毕时一定是最优解

对于邻接矩阵w,w保存最初始情况下任意两点间的直接最短距离,但没有加入中继点进行考虑
如w[1][2]=20,即表示点1与点2的当前最短距离(直接距离)为20

对于路径矩阵path,保存了点i到点j的最短路径中下一个点的位置,
如path[1][2]=0,表示1->2的路径中的下一个点为结点0

Floyd算法对所有中继点在任意两点中进行循环遍历.即k从0-n时考虑(i->k,k->j)的路径是否小于(i->j)的路,如果小于即更新邻接矩阵w的值与path矩阵中的值,使其始终保持最短
图解如下:

代码用例:

代码如下

点击查看代码
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
const int MAX = 999;
class Solution {
public:
	void GetPath(vector<vector<int>>vec,int n) {
		
		vector<vector<int>>path(n);

		//初始化
		for (int i = 0; i != n; i++)
			path[i].resize(n);

		for(int i=0;i!=n;i++)
			for (int j = 0; j != n; j++) {
				if (vec[i][j] != MAX)path[i][j] = j;
				else path[i][j] = -1;
			}

		for (int i = 0; i < n; i++)path[i][i] = -1;
		for(int k=0;k!=n;k++)
			for(int i=0;i!=n;i++)
				for (int j = 0; j != n; j++) {
					if (vec[i][k] + vec[k][j] < vec[i][j]) {
						vec[i][j] = vec[i][k] + vec[k][j];
						path[i][j] = path[i][k];
					}
				}
				
		for (int i = 0; i != n; i++)
		{
			cout << "\\nStating from vertex: " << i << endl;
			bool flag = 0;
			for (int j = 0; j != n; j++)
				if (j != i && vec[i][j] < MAX) {
					flag = 1;
					cout << i << "->" << j << ":distance=" << vec[i][j] << ": " << i;
					int k = path[i][j];
					while (k != j) {
						cout << "->" << k;
						k = path[k][j];
					}
					cout << "->" << j << endl;
				}

			if (!flag)cout << "there\'s no path while starting from "<<i<<endl;
		}
	}
};
int main() {
	ifstream putIn("D:\\\\Input.txt", ios::in);
	int num;
	int finalCount = 0;
	putIn >> num;
	const int x = num;
	vector<vector<int>>myVector(num);
	//myVector:带权邻接矩阵
	for (int i = 0; i < num; i++)
		myVector[i].resize(num);
	for (int i = 0; i < num; i++)
		for (int j = 0; j < num; j++) {
			int temp;
			putIn >> temp;
			myVector[i][j] = temp;
		}
	Solution solution;
	cout << "Input文件中的邻接矩阵为\\n";
	for (auto x : myVector) {
		for (auto y : x)cout << y << \'\\t\';
		cout << endl;
	}
	solution.GetPath(myVector,num);
	return 0;
}

我是一个还没有想好写点啥的小尾巴

以上是关于关于Floyd算法,path数组一定能保存正确的路径吗?的主要内容,如果未能解决你的问题,请参考以下文章

Floyd佛洛伊德算法

Floyd算法——保存路径——输出路径 HDU1385

最短路径——Floyd算法

图论模型---floyd算法

C++实现一个简单的Floyd算法

C++实现一个简单的Floyd算法