Floyd算法计算最短距 + 记录经过的节点

作用:寻找最短路径
与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")
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.breeze.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值