在循环加权图中寻找最短路径

时间:2018-03-18 23:02:17

标签: python graph-algorithm path-finding

我试图在循环加权图中找到最短路径。我有以下递归函数,如果它们不是循环的,它们能够找到2个点之间的最短路径。例如,我的图表看起来像这样:

width: calc((100% - 20px) / 3);

现在我发现shortestRoute函数看起来像这样

graph = {
          'A': {'B': 5, 'D': 5, 'E': 7 },
          'B': {'C': 4},
          'C': {'D': 8, 'E': 2},
          'D': {'C': 8, 'E':  6},
          'E': {'B': 3}
        }

现在对于非循环的情况,如果我做

这样的事情
def findShortestRoute(self, start, end , weight, shortestRoute):
    # sys.setrecursionlimit(10000)
    visited = []
    # Check if start and end nodes exists in route table
    if start in self.routesTable and end in self.routesTable:
        visited.append(start) # mark start to visited

        for adj in self.routesTable[start]:
            if(adj == end or adj not in visited):
                weight += self.routesTable[start][adj]

            '''
            If destination matches, we compare
            weight of this route to shortest route
            so far, and make appropriate switch
            '''

            if adj == end:
                if shortestRoute == 0 or weight < shortestRoute:
                    shortestRoute = weight
                visited.remove(start)
                return shortestRoute
            '''
            If destination does not match, and
            destination node has not yet been visited,
            we recursively traverse destination node
            '''
            if adj not in visited:
                shortestRoute = self.findShortestRoute(adj, end, weight, shortestRoute)
                weight -= self.routesTable[start][adj]

    else:
        return "No such route exists"

    if start in visited:
        visited.remove(start)

    return shortestRoute

这将返回9,这是预期的。但是,如果我做这样的事情 findShortestRoute('B','B',0,0)

该功能将达到堆栈溢出。然而,由于图形是循环的,因此有一种方法可以从B开始并返回B.在这种情况下,B-C-E-B的权重为9。 但我的功能是达到最大递归。如果有人可以帮助我,我真的很感激。提前致谢

1 个答案:

答案 0 :(得分:1)

您的问题是您没有通过递归传递visited列表,因此您的算法会在周期中陷入困境。如果传递前任节点,则可以检测周期并在遇到周期时返回。

这是我改变你的代码来实现这个目标的方法:

def findShortestRoute(start, end , weight, shortestRoute, visited, routesTable):
# sys.setrecursionlimit(10000)
# Check if start and end nodes exists in route table

if start in routesTable and end in routesTable:
    if start in visited:
        return 99999
    visited.append(start) # mark start to visited

    for adj in routesTable[start]:
        if(adj == end or adj not in visited):
            weight += routesTable[start][adj]

        '''
        If destination matches, we compare
        weight of this route to shortest route
        so far, and make appropriate switch
        '''

        if adj == end:
            if shortestRoute == 0 or weight < shortestRoute:
                shortestRoute = weight
            visited.remove(start)
            return shortestRoute
        '''
        If destination does not match, and
        destination node has not yet been visited,
        we recursively traverse destination node
        '''
        if adj not in visited:
            shortestRoute = findShortestRoute(adj, end, weight, shortestRoute, visited, routesTable)
            weight -= routesTable[start][adj]
else:
    return "No such route exists"


return shortestRoute

graph = {'A': {'B': 5, 'D': 5, 'E': 7 },'B': {'C': 4},'C': {'D': 8, 'E': 2},'D': {'C': 8, 'E':  6},'E': {'B': 3}}

print(findShortestRoute('B', 'B', 0, 0, [], graph))