图(四)之Adjecancy Matrix的Floyd算法

上一篇关于Dijkstra算法的实现发现一个问题,就是Dijkstra算法主要针对的是一个顶点到其他顶点间的最小距离,那么问题来了,如何实现每一对顶点间的最小距离,是选择Dijkstra算法进行n次遍历?显然发现会很麻烦,对于n次遍历的Dijkstra算法,时间复杂度为O(n^3)。这里介绍的Floyd算法时间复杂度算然和前者相同,但是至少实现的形式上能简单一些!

Floyd算法基本思想是:

假设求从顶点vi到vj的最短路径。如果从vi到vj有弧,则从vi到vj存在一条长度为arc[i][j]的路径,该路径不一定是最短路径,尚需进行n次试探。首先考虑路径(vi,vj)和(vi,v0,vj)是否存在(即判别弧(vi,v0)和(v0,vj)是否存在)。如果存在,则比较(vi,vj)和(vi,v0,vj)的路径长度取长度较短者为从vi到vj的中间顶点的序号不大于0的最短路径。假设在路径上在增加一个顶点v1,也就是说,如果(vi,...,v1)和(v1,.....,vj)分别是当前找到的中间顶点的序号不大于0的最短路径,那么(vi,...,v1,...vj)就用可能是从vi到vj的中间点点序号不大于1的最短路径。讲他和已经得到的从vi到vj中间顶点序号不大于0的最短路径比较,从中选出中间顶点的序号不大于1 的最短路径之后在增加一个顶点v2,继续进行试探。此时我们需要借助三阶矩阵来实现这个过程的存储。

下面把算法伪代码贴出来:


给出书中的测试用例图:


还有建立的辅助矩阵:


下面分享代码:

/*
 ************************************************
 *Name : Matrix_Floyd.c                         *
 *Date : 2015-06-17                             *
 *Author : sniper                               *
 *Aim : Floyd algrithm to get the shortest route*
 *      each node to others in the graph        *
 ************************************************
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_MATRIX_NUMBER 100
#define INF 32768

int main()
{
	int i,j,k,l; 
	int node_count,edge_count;
	int node_pair1,node_pair2,weight;
	int Distance[MAX_MATRIX_NUMBER][MAX_MATRIX_NUMBER];
	int edge[MAX_MATRIX_NUMBER][MAX_MATRIX_NUMBER];
	int Path[MAX_MATRIX_NUMBER][MAX_MATRIX_NUMBER];

	node_count=edge_count=node_pair1=node_pair2=weight=0;	
	printf("please input the number of node and edge: ");
	scanf("%d %d",&node_count,&edge_count);	
	memset(Distance,0,sizeof(Distance));
	memset(edge,0,sizeof(edge));
	memset(Path,0,sizeof(Path));

	/*
	 *Create the graph
	 */
	for(i=0;i<edge_count;i++)
	{
		printf("please input the node pair: ");  
		/*
		 *node_pair1 node_pair2 two side of edge and 
		 *the weight means the weight of edge
		 */
		scanf("%d %d %d",&node_pair1,&node_pair2,&weight); 					
		edge[node_pair1][node_pair2] = weight;
	}
	printf("after create the graph is :\n");  
	for(i=0;i<node_count;i++)
	{
		for(j=0;j<node_count;j++)
		{
			if(i!=j && edge[i][j]==0)
				edge[i][j]=INF;
			printf(" %d ",edge[i][j]);
		}
		printf("\n");
	}

	/*
	 *Floyd
	 */
	for(i=0;i<node_count;i++)
	{
		for(j=0;j<node_count;j++)
		{
			Distance[i][j]=edge[i][j];
				printf(" %d ",Distance[i][j]);
			for(k=0;k<node_count;k++)
				if(Distance[i][j]>0)
				{
					(Path+i)[j][i]=1;
					(Path+i)[j][j]=1;
				}
		}
		printf("\n");
	}
	printf("+++++++++++++++++++++++++++++++++\n");
	for(i=0;i<node_count;i++)
		for(j=0;j<node_count;j++)
			for(k=0;k<node_count;k++)
				if(Distance[j][i]+Distance[i][k]<Distance[j][k])
				{
					Distance[j][k]=Distance[j][i]+Distance[i][k];
					for(l=0;l<node_count;l++)
						(Path+j)[k][l] = (Path+j)[i][l]||(Path+i)[k][l];
				}
	for(i=0;i<node_count;i++)
	{
		for(j=0;j<node_count;j++)
		{
			if(Distance [i][j]!=0)			
			{
				printf("%c -> %c = %d \n",i+'A',j+'A',Distance[i][j]);
			}
		}
	}
	return 0;
}
当然了还有测试用例:

3 5
0 1 4
0 2 11
1 0 6
1 2 2
2 0 3

运行结果如下图:


大家可以去我的github clone一下代码:

https://github.com/cremyos/Graph_Floyd/

这个代码无法打印详细的路径,因为在84行处的

(Path+j)[k][l] = (Path+j)[i][l]||(Path+i)[k][l];

应该是把路径拼接起来,结果采用的是或运算,所以出问题了,具体怎么改。。。还没想到什么好的办法!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值