图论算法之最短路径
图论算法之最短路径
是什么?
图(graph)是数据结构和算法学中最强大的框架之一(或许没有之一)。图几乎可以用来表现所有类型的结构或系统,从交通网络到通信网络,从下棋游戏到最优流程,从任务分配到人际交互网络,图都有广阔的用武之地,而最短路径求解问题是图论的研究的重点之一。最短路径表示用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
解法种类?
(1)Dijkstra算法
(2)SPFA算法\Bellman-Ford算法
(3)Floyd算法\Floyd-Warshall算法
(4)Johnson算法
(5)A*算法
我们这里考虑的是 Floyd算法\Floyd-Warshall算法
解法的思路和代码形成
Floyd-Warshall算法是解决任意两点间的最短路径的一种算法。通常可以在任何图中使用,包括无向图、有向图、带权和带负权边的图。
思路:
单独一条边的路径也不一定是最佳路径。 从任意一条单边路径开始。所有两点之间的距离是边的权的和,(如果两点之间没有边相连, 则为无穷大)。 从第一个顶点开始,依次将每个顶点作为媒介 k,然后对于每一对顶点 u 和 v ,查看其是否存在一条经过 k 的,距离比已知路径更短的路径,如果存在则更新它。
即:dist[k](i,j) = min(dist[k-1](i,j),dist[k-1](i,k)+dist[k-1](k,j) #dist[k](i,j) 为媒介结点为k时从节点 i 到节点 j 的最短距离。
以上述可以得出如下视图:
n=int(input()) #表示输入节点的个数 a=[[0]*n for i in range(n)] #a列表的作用是用来进行存储两个节点之间的最短距离(即a[i][j]表示为i节点到j节点的最短路径) b=[] #先临时存储用户通过键盘输入的数 for i in range(0,n): for j in input().split(' '): b.append(eval(j)) for i in range(0,n): for j in range(0,n): a[i][j]=b[i*n+j] for k in range(0,n): #表示为从第一个结点开始,依次将每个节点作为媒介k,防止遗漏结果。 for i in range(0,n): #将每个节点都与其他的节点进行一次最短距离的比较 for j in range(0,n): if a[i][j]>a[i][k]+a[k][j]: #若a[i][j]>a[i][k]+a[k][j],则说明i到j的可以通过媒介进行缩减,之后将i到j的最短距离进行更新 a[i][j]=a[i][k]+a[k][j] k=0 for i in range(0,n): #打印出每两个节点之间的最短距离 for j in range(0,n): if k%n==0 and k!=0: print() print(a[i][j],end=' ') k+=1
总结:
根据该最短路径的求解方法,我们可以将求解最短路径问题进行延申。
例如:①求解城市建造问题(怎样花费最小)
②旅行商问题等(给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。)
可以先利用Floyd 算法求解最短路径。先求解第一个城市与其他城市的距离相加,然后在求解第二个城市到每个城市的距离和,以此类推。得到最大的值,根据最大值来得到将哪个城市作为主城市。