【算法导论】每对顶点之间的最短路径算法

简介:         对于一个顶点数为N的有向网路图,我们可以通过前面所提到的单源最短路径算法执行N次来获得每一对顶点间的最短路径。这种方法的时间复杂度为O(N*N*N)。

        对于一个顶点数为N的有向网路图,我们可以通过前面所提到的单源最短路径算法执行N次来获得每一对顶点间的最短路径。这种方法的时间复杂度为O(N*N*N)。如果网络中有负权值的边,则需要使用前面提到的单源最短路径算法之Bellman—Floyd算法。总之,总可以通过单源最短路径来求得每对顶点间的最短路径。这里我就不再用程序实现上述方法,下面介绍Floyd解决这一问题的另一种算法,它形式简单,利于理解,而且时间复杂度同样为O(N*N*N)。

       Floyd算法是根据给定有向网络的邻接矩阵dist[n][n]来求顶点vi到顶点vj的最短路径。这一算法的基本思想是:假设vi和vj之间存在一条路径,但这并不一定是最短路径,试着在vi和vj之间增加一个中间顶点vk。 若增加vk后的路径(vi, vk, vj) 比(vi, vj)短,则以新的路径代替原路径,并且修改dist[i][j]的值为新路径的权值;若增加vk后的路径比(vi, vj)更长,则维持dist[i][j]不变。然后在修改后的dist矩阵中,另选一个顶点作为中间顶点,重复以上的操作,直到除vi和vj顶点的其余顶点都做过中间顶点为止。下面以具体实例来说明问题:

假设有向网路图如下所示:


设原始的最短路径矩阵为L(1),经过一次循环后得到新的最短矩阵为L(2),依此类推,当得到L(N-1)时,我们就得到了最短的路径矩阵。最短路径矩阵的变化情况如下:


具体程序实现如下:

#include<stdio.h>

#define N 5 //顶点个数
#define MAX 10000

void Floyd(int dist[N][N],int A[N][N],int path[N][N])
{


	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			for(int k=0;k<N;k++)
			{
				/*if(A[i][j]>(A[i][k]+dist[k][j]))//方法一:计算每一次矩阵
				{
					A[i][j]=(A[i][k]+dist[k][j]);
					path[i][j]=path[k][j];
				}*/
				if(A[i][j]>(A[i][k]+A[k][j]))//方法二:计算2的幂次矩阵
				{
					A[i][j]=(A[i][k]+A[k][j]);
					path[i][j]=path[k][j];
				}
			}
}

void main()
{
	int dist[N][N]={{0,3,8,MAX,-4},//图的邻接矩阵
	                {MAX,0,MAX,1,7},
	                {MAX,4,0,MAX,MAX},
	                {2,MAX,-5,0,MAX},
	                {MAX,MAX,MAX,6,0}};
	int A[N][N];
	int path[N][N]={0};//给出两顶点间的路径
	int pre=0;

	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
		{
			A[i][j]=dist[i][j];
			if(dist[i][j]!=MAX)
				path[i][j]=i+1;
			else
				path[i][j]=0;
		}
	
	for(int k=0;k<2;k++)//若用方法一,需循环N-3次,若用方法二,需要循环lg(N-1)次
		Floyd(dist,A,path);

	printf("每对顶点间的最短路径矩阵为:\n");
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<N;j++)
			printf("%d ",A[i][j]);
		printf("\n");
	}
	printf("\n每对顶点的具体最短路径为:\n");
	
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<N;j++)
		{
			printf("%d: %d ",A[i][j],j+1);
		pre=path[i][j];
		while((pre!=0)&&(pre!=i+1))
		{
			printf("<- %d ",pre);
			pre=path[i][pre-1];
		}
		printf(" <- %d\n",i+1);
		}
	}
}

结果显示如下:



程序不但显示了两点之间的最短路径长度,而且显示了具体的路径。在程序中,我用了两种方法求最短路径矩阵,其中第二种方法更加简单的,因为我们要求的最短路径矩阵为L(N-1)。比如说当N=5时,我们需要最终得到L(4),我们可以只求L(1)、L(2)、L(4),而不需要求得每一个L。


注:如果程序出错,可能是使用的开发平台版本不同,请点击如下链接: 解释说明


原文:http://blog.csdn.net/tengweitw/article/details/17577623

作者:nineheadedbird


目录
相关文章
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
82 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
4月前
|
自然语言处理 算法
HanLP — HMM隐马尔可夫模型 - 路径规划算法 - 求解最短路径 - 维特比(Viterbi)算法
HanLP — HMM隐马尔可夫模型 - 路径规划算法 - 求解最短路径 - 维特比(Viterbi)算法
61 0
HanLP — HMM隐马尔可夫模型 - 路径规划算法 - 求解最短路径 - 维特比(Viterbi)算法
|
5月前
|
算法 Java
Java语言实现最短路径算法(Shortest Path)
Java语言实现最短路径算法(Shortest Path)
62 3
|
4月前
|
算法 定位技术
路径规划算法 - 求解最短路径 - A*(A-Star)算法
路径规划算法 - 求解最短路径 - A*(A-Star)算法
101 0
|
4月前
|
算法
路径规划算法 - 求解最短路径 - Dijkstra(迪杰斯特拉)算法
路径规划算法 - 求解最短路径 - Dijkstra(迪杰斯特拉)算法
74 0
|
6月前
|
算法 Java
Java数据结构与算法:最短路径算法
Java数据结构与算法:最短路径算法
|
6月前
|
算法 Java 定位技术
Java数据结构与算法:贪心算法之最短路径
Java数据结构与算法:贪心算法之最短路径
|
2月前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
12天前
|
算法 数据安全/隐私保护 索引
OFDM系统PAPR算法的MATLAB仿真,对比SLM,PTS以及CAF,对比不同傅里叶变换长度
本项目展示了在MATLAB 2022a环境下,通过选择映射(SLM)与相位截断星座图(PTS)技术有效降低OFDM系统中PAPR的算法实现。包括无水印的算法运行效果预览、核心程序及详尽的中文注释,附带操作步骤视频,适合研究与教学使用。
|
20天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。