最短路径经典算法其三——Floyd

前言

  hello,大家好吖,继我们上次讲了最短路径经典算法的 DijkstraBellman-Ford 算法之后,相信大家对于最短路径的求解方法已经有了一些概念和基础,还有点迷糊的可以顺着代码的思路去画个图或者让程序打印出每一步的中间结果,就可以很明显地看出执行过程啦~

  今天我们来讲最短路径经典算法其三—— Floyd算法。Floyd是多源多点的最短路径求解算法,之前讲的两个都是单源单点,如果要求任意一个节点A到节点B的最短路径,对于n个节点的无负环图我们需要运行n次Dijksta或者Bellman-Ford才可以得到所有可能的路径。所以今天讲的Floyd对于那种稠密图即节点很多,节点间的连接也很多的图来说效率更高,一次求解便可以得到任意节点到其他节点的最短路径。

优快云 (゜-゜)つロ 干杯

算法代码模板和原理讲解

  Floyd算法的代码模板相比其他两个简单的多,本质上就是三重循环的贪心求解过程:

for k in range(N):  # 可使用的节点集合范围0~n-1
		for i in range(N):  # 起点
			for j in range(N):  # 终点
				ad_mat[i][j] = min(ad_mat[i][j], ad_mat[i][k]+ad_mat[k][j])

  请记住上面的模板,很多题目的解都可以直接套用,复杂一点的可能需要增加一些判断条件,主体逻辑还是依旧。

  我们可以知道,节点A到节点B的最短路径无非两种情况

  1. 节点A直接到节点B最短
  2. 节点A通过一些中间节点C,D,…… 到达节点B最短

  Floyd就是去在所有可能成为中间节点的集合里去寻找是否存在使得路径更短的节点组合所以第一层循环可以理解为在所有节点组成的中间节点集合中找备选组(找备胎?? ),而后两层循环就是列举起点和终点的组合

  是不是有点穷举和贪心那味儿了~时间复杂度也很容易看出
O ( N 3 ) O(N^3) O(N3)
  

代码实现

  我们来看看针对一般性最短路径的代码实现:

def Floyd(directed=True):
	"""
		Simple implement of Floyd Algorithm

	Args:
		directed (bool, optional): [whether directed graph or not]. Defaults to True.
	"""
	N, K, s, e = list(map(int, input().split()))  # 节点数、连接数、起点终点标号
	limit = 10000
	ad_mat = [[limit for i in range(N)] for j in range(N)]  # 邻接矩阵
	for i in range(K):
		u, v, w = list(map(int, input().split()))
		ad_mat[u][v] = w
		# 无向图
		if not directed:
			ad_mat[v][u] = w
	for i in range(N):
		ad_mat[i][i] = 0

	# core
	for k in range(N):  # 可使用的节点集合范围0~n-1
		for i in range</
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值