📅  最后修改于: 2023-12-03 14:40:35.892000             🧑  作者: Mango
DAA算法也称为约翰逊算法是一种基于Dijkstra算法优化了负权边的最短路径算法。它是由Neil D. Jones和Cristopher M. Fredriksen发明的。与Dijkstra算法相比,它具有更快的时间复杂度,可以更有效地处理负权边的情况,并且可以解决保真的有向图及其变种。
以下是Python实现的DAA算法示例代码:
from queue import Queue
from typing import List, Tuple
def daa(graph: List[List[Tuple[int, int]]]) -> List[int]:
def spfa(source: int) -> List[int]:
distance = [float('inf')] * (n + 1)
inqueue = [False] * (n + 1)
q = Queue()
distance[source] = 0
inqueue[source] = True
q.put(source)
while not q.empty():
u = q.get()
inqueue[u] = False
for v, w in graph[u]:
if distance[v] > distance[u] + w:
distance[v] = distance[u] + w
if not inqueue[v]:
q.put(v)
inqueue[v] = True
return distance
n = len(graph) - 1
# Step 1
graph.append([(i, 0) for i in range(1, n + 1)])
# Step 2
distance_s = spfa(n + 1)
if distance_s[n + 1] < 0: # 有负环
return None
# Step 3
h = distance_s[n + 1]
for i in range(1, n + 1):
graph[i].append((n + 1, h - distance_s[i]))
# Step 4
distance_i = spfa(n + 1)
# Step 5
result = [0] * n
for i in range(1, n + 1):
result[i - 1] = distance_i[i] + distance_s[i] - h
return result
代码片段开头使用了队列Queue,需要先导入Queue类。
在主函数daa中先进行了Step 1,Step 2,Step 3三步,得到了优化后的图结构以及源节点到各节点的相对权值。然后进行Step 4,再次用SPFA算法计算每个节点的最短路径。最后Step 5,对每个节点的最短路径进行优化,得到其实际权重。