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

我用Python实现了基本的线性最短路径算法。根据我遇到的各种网站,这只适用于有向无环图,包括,和。然而,我不明白为什么会这样

我甚至对带有圈和无向边的图测试了该算法,效果很好

所以问题是,为什么线性最短路径算法不适用于无向循环图?次要问题,该算法的名称是什么?

以下是我为算法编写的代码供参考:

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可能会在拓扑顺序方面给你不同的结果。由于随后的最短路径处理依赖于该顺序,因此您的结果通常不正确。