Python 为什么';线性最短路径算法是否适用于无向循环图?
我用Python实现了基本的线性最短路径算法。根据我遇到的各种网站,这只适用于有向无环图,包括,和。然而,我不明白为什么会这样 我甚至对带有圈和无向边的图测试了该算法,效果很好 所以问题是,为什么线性最短路径算法不适用于无向循环图?次要问题,该算法的名称是什么? 以下是我为算法编写的代码供参考:Python 为什么';线性最短路径算法是否适用于无向循环图?,python,algorithm,graph,shortest-path,directed-acyclic-graphs,Python,Algorithm,Graph,Shortest Path,Directed Acyclic Graphs,我用Python实现了基本的线性最短路径算法。根据我遇到的各种网站,这只适用于有向无环图,包括,和。然而,我不明白为什么会这样 我甚至对带有圈和无向边的图测试了该算法,效果很好 所以问题是,为什么线性最短路径算法不适用于无向循环图?次要问题,该算法的名称是什么? 以下是我为算法编写的代码供参考: def shortestPath(start, end, graph): # First, topologically sort the graph, to determine which or
def shortestPath(start, end, graph):
# First, topologically sort the graph, to determine which order to traverse it in
sorted = toplogicalSort(start, graph)
# Get ready to store the current weight of each node's path, and their predecessor
weights = [0] + [float('inf')] * (len(graph) - 1)
predecessor = [0] * len(graph)
# Next, relaxes all edges in the order of sorted nodes
for node in sorted:
for neighbour in graph[node]:
# Checks if it would be cheaper to take this path, as opposed to the last path
if weights[neighbour[0]] > weights[node] + neighbour[1]:
# If it is, then adjust the weight and predecessor
weights[neighbour[0]] = weights[node] + neighbour[1]
predecessor[neighbour[0]] = node
# Returns the shortest path to the end
path = [end]
while path[len(path) - 1] != start:
path.append(predecessor[path[len(path) - 1]])
return path[::-1]
编辑:根据Beta的要求,这里是拓扑排序:
# Toplogically sorts the graph given, starting from the start point given.
def toplogicalSort(start, graph):
# Runs a DFS on all nodes connected to the starting node in the graph
def DFS(start):
for node in graph[start]:
if not node[0] in checked:
checked[node[0]] = True
DFS(node[0])
finish.append(start)
# Stores the finish point of all nodes in the graph, and a boolean stating if they have been checked
finish, checked = [], {}
DFS(start)
# Reverses the order of the sort, to get a proper topology; then returns
return finish[::-1]
因为不能用循环对图进行拓扑排序(因此无向图也是不可能的,因为您无法判断哪个节点应该位于另一个节点之前)
编辑:在阅读了评论之后,我认为@Beta实际上就是这个意思。因为你不能用循环对一个图进行拓扑排序(因此无向图也是不可能的,因为你不知道哪个节点应该在另一个节点之前)
编辑:阅读评论后,我认为@Beta实际上就是这个意思。当存在循环时,拓扑排序不能保证最短路径的正确排序 例如,我们有一个图表:
A->C, A->B, B->C, C->B, B->D
假设正确的最短路径是:
A->C->B->D
但是拓扑排序可以生成一个顺序:
A->B->C->D
虽然在访问
C
时它会将B
更新为正确的顺序,但是B
不会再次访问,因此无法将正确的权重传播到D
。(路径恰好是正确的。)当存在循环时,拓扑排序不能保证最短路径的正确排序
例如,我们有一个图表:
A->C, A->B, B->C, C->B, B->D
假设正确的最短路径是:
A->C->B->D
但是拓扑排序可以生成一个顺序:
A->B->C->D
虽然在访问
C
时它会将B
更新为正确的顺序,但是B
不会再次访问,因此无法将正确的权重传播到D
。(不过路径恰好是正确的。)您第一次参考中的算法涉及图形的拓扑排序。如何使用包含一个循环的图形来实现这一点?将该方法添加到问题中,而不是“如何实现它”。问题是,你认为对循环图进行拓扑排序意味着什么?如果它不是非循环图,DFS在图上创建的顺序取决于它的表示方式以及图的拓扑。我的意思是:如果你使用相同的循环图,并将其存储在内存中的两种不同结构中(例如,作为具有不同顺序的邻接列表),DFS可能会在拓扑顺序方面给你不同的结果。由于随后的最短路径处理依赖于该顺序,因此您的结果通常不正确。您第一次参考中的算法涉及图形的拓扑排序。如何使用包含一个循环的图形来实现这一点?将该方法添加到问题中,而不是“如何实现它”。问题是,你认为对循环图进行拓扑排序意味着什么?如果它不是非循环图,DFS在图上创建的顺序取决于它的表示方式以及图的拓扑。我的意思是:如果你使用相同的循环图,并将其存储在内存中的两种不同结构中(例如,作为具有不同顺序的邻接列表),DFS可能会在拓扑顺序方面给你不同的结果。由于随后的最短路径处理依赖于该顺序,因此您的结果通常不正确。