Floy算法

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;
}

运行结果如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值