从头到尾找到图中的最短路径

时间:2015-11-06 15:46:20

标签: python algorithm graph

我试图找到图表中所有可能路径中的最短路径。我编写了下面的程序,当我尝试从顶点'A'到'D'搜索路径时,它返回['A','B','C','D']。但最短的距离是['A','B','D']。有没有办法找到它,因为我已经找到了所有可能的节点?

from collections import defaultdict


def find_path(graph,start,end,path=[]):
    path = path + [start]
    print "intermediate", path
    if start == end:
        return path
    if not graph.has_key(start):
        return None
    for node in graph[start]:
        print "node",node
        if node[1] not in path:
            newpath = find_path(graph,node[1],end,path)
            if newpath :
                return newpath
    return None

if __name__ == '__main__':
    graph = defaultdict(list)
    graph = { 
            'A': [('A','B'),('A','C')],
            'B' : [('B','C'),('B','D')],
            'C' : [('C','D')],
            'D' : [('D','C')],
            'E' : [('E','F')],
            'F' : [('F','C')]
            }

    path = find_path(graph,'A','D')

1 个答案:

答案 0 :(得分:0)

我现在添加了一个新功能,通常是一种贪婪的算法。如果它看到一个连接到'end'节点的节点,它会关闭递归。谢谢@Jonathan的建议。对此方法的任何批评都会感激不尽。

def shortest_path(graph,start,end,short_path=[]):
    short_path = short_path + [start]
    #print "Initial short path",short_path
    if start == end:
        return short_path
    if not graph.has_key(start):
        return None
    for node in graph[start]:
        #print "short node",graph[start]
        vend = [x[1] for x in graph[start] if x[1] == end]
        print "v_end",vend
        if vend :
            if vend[0] == end:
                #print "printing end nodes",vend,start
                tmp_path = shortest_path(graph,end,end,short_path)
                if tmp_path:
                    #print "shortest intermediate path",tmp_path
                    return tmp_path

        elif node[1] not in short_path:
            tmp_path = shortest_path(graph,node[1],end,short_path)
            #print tmp_path, "start",node[1], "end",end
            if tmp_path:
                #print "shortest intermediate",tmp_path
                return tmp_path
        else:
            return None