作用:寻找最短路径
与Dijkstra的区别:主要计算多源最短路径
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。
算法的具体思想:
1 .邻接矩阵(二维数组)dist储存路径,数组中的值开始表示点点之间初始直接路径,最终是点点之间的最小路径,有两点需要注意的,第一是如果没有直接相连的两点那么默认为一个很大的值,第二是自己和自己的距离要为0。
2 .从第1个到第n个点依次加入松弛计算,每个点加入进行试探枚举是否有路径长度被更改(自己能否更新路径)。顺序加入(k枚举)松弛的点时候,需要遍历图中每一个点对(i,j双重循环),判断每一个点对距离是否因为加入的点而发生最小距离变化,如果发生改变(变小),那么两点(i,j)距离就更改。
3 .重复上述直到最后插点试探完成。
第二步的状态转移方程:dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])
所以最后得到的矩阵中:dp[a][b]的意思可以理解为点a到点b的最短路径,所以dp[i][k]的意思可以理解为i到k的最短路径dp[k][j]的意思为k到j的最短路径.
在本例代码中,way存储所经路程,p适用于求所经路程的点,a最后是存最短路径的矩阵(刚开始显示的是权重)
def floyd(self,a):
global way
way={}
p=np.mat(np.zeros((4, 4)))
for i in range(0,4):
for j in range(0,4):
p[i,j]=j+1
if (i!=j) and (a[i,j]==0):
a[i,j]=float("inf")
#print (a)
for k in range(0,4):
for l in range(0,4):
for m in range(0,4):
if a[l,m]>a[l,k]+a[k,m]:
a[l,m]=min(a[l,m],a[l,k]+a[k,m])
p[l,m]=p[l,k]
for i in range(0,4):
for j in range(0,4):
#print("s%d-->s%d minway:%d"%((i+1),(j+1),a[i,j]))
k=int(p[i,j])-1
#print("s%d"%(i+1))
way[str(i+1)+":"+str(j+1)]=str(i+1)
while k!=j:
#print("-> s%d"%(k+1))
way[str(i+1)+":"+str(j+1)]+=str(k+1)
j=int(j)
k=p[k,j]-1
#print("-> s%d"%(j+1))
way[str(i+1)+":"+str(j+1)]+=str(j+1)
print(way)
print("\n")