Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。
算法思想:
1、Floyd算法递归地产生一个矩阵序列adj(0),adj(1),…, adj(k) ,…, adj(n)
2、adj(k)[i,j]等于从顶点Vi到顶点Vj中间顶点序号不大于k的最短路径长度
假设已求得矩阵adj(k-1),那么从顶点Vi到顶点Vj中间顶点的序号不大于k的最短路径有两种情况:
(1)一种是中间不经过顶点Vk,那么就有adj(k)[i,j]=adj(k-1)[i,j]
(2)另一种是中间经过顶点Vk,那么adj(k)[i,j]< adj(k-1)[i,j],且adj(k)[i,j]= adj(k-1)[i,k]+ adj(k-1)[k,j]
图解过程如下:
代码如下:
#include "GraphLink.h"
class Dist
{
public:
int index; //顶点的索引值,仅Dijkstra算法会用到
int length;//顶点之间的距离
int pre;//路径最后经过的顶点
bool operator < (const Dist &dist)
{
return length < dist.length;
}
bool operator <= (const Dist &dist)
{
return length <= dist.length;
}
bool operator > (const Dist &dist)
{
return length > dist.length;
}
bool operator >= (const Dist &dist)
{
return length >= dist.length;
}
bool operator == (const Dist &dist)
{
return length == dist.length;
}
};
//Floyd算法
void floyd(Graph& G, Dist** &D)
{
D = new Dist*[G.verticesNum()];// 为数组D申请空间
for(int i = 0; i < G.verticesNum(); i++)
{
D[i] = new Dist[G.verticesNum()]; // 初始化数组D
}
for(int i = 0; i < G.verticesNum();i++)
{
for(int j = 0; j < G.verticesNum(); j++)
{
if(i == j)
{
D[i][j].length = 0;
D[i][j].pre = i;
}
else
{
D[i][j].length = INFINITE;
D[i][j].pre = -1;
}
}
}
for(int i = 0; i < G.verticesNum();i++)
{
for(Edge edge = G.firstEdge(i);G.isEdge(edge); edge = G.nextEdge(edge))
{
D[i][G.toVertex(edge)].length = G.weight(edge);
D[i][G.toVertex(edge)].pre = i;
}
}
//算法的核心: 如果两个顶点间的最短路径经过顶点v,则更新最短距离
for(int v = 0; v < G.verticesNum();v++)
{
for(int i = 0; i < G.verticesNum();i++)
{
for(int j = 0; j < G.verticesNum(); j++)
{
if (D[i][j].length > (D[i][v].length+D[v][j].length))
{
D[i][j].length = D[i][v].length+D[v][j].length;
D[i][j].pre = D[v][j].pre;
}
}
}
}
}
//
int A[N][N] = {
// v0 v1 v2
/*v0*/ 0, 4, 11,
/*v1*/ 6, 0, 2,
/*v2*/ 3, INFINITE, 0
};
int main()
{
GraphLink<ListUnit> graphLink(N); // 建立图
graphLink.initGraph(graphLink, A,N); // 初始化图
Dist **dist;
floyd(graphLink,dist);
for (int i = 0; i < N; i ++) {
for (int j = 0; j < N; j ++)
cout << dist[i][j].length << " ";
cout << endl;
}
system("pause");
return 0;
}
运行结果如下: