BFS最短路径记录问题的解决(python)

广度优先遍历
常用的解决无权重最短路径问题方法,其核心在于使用队列“先进先出”的特点,能快速找到最靠近起始节点的目标节点。
问题
由于各节点顺序进队出队,在查找到目标节点后很难追溯最短路径。
解决方案
参考Dijkstra算法,额外增加parents散列表,记录下能使入队节点被最早发现的父节点,即当节点入队时候,一起更新入队节点的父节点信息,以方便后续路径追溯。
代码
路径图如下

         A--1--C
     6 / |     |1
   start |3 final
      2\ | /5
         B

def creat_graph():
    """字典嵌套字典实现带权重有向路径图"""
    graph = dict()

    graph["start"] = dict()
    graph["start"]['a'] = 6
    graph["start"]['b'] = 2

    graph["a"] = dict()
    graph["a"]['c'] = 1

    graph["c"] = dict()
    graph["c"]['fin'] = 1

    graph["b"] = dict()
    graph["b"]['a'] = 3
    graph["b"]['fin'] = 5

    graph["fin"] = dict()

    return graph

创建父节点散列表

def parents_table():
    # 创建存储父节点的散列表
    parents = dict()
    parents['a'] = None
    parents['b'] = None
    parents['c'] = None
    parents['fin'] = None
    return parents

BFS实现

def BFS(graph, start, end, parents):
    """广度优先遍历,搜寻最短路径"""
    from collections import deque       # 创建搜索队列
    search_queue = deque()
    # 队列中添加起始点,并记录邻居节点父节点
    for node in graph[start]:
        if not parents[node]:
            parents[node] = 'start'
        search_queue.append(node)
    searched = []       # 记录已查找节点

    while search_queue:
        node = search_queue.popleft()
        if node not in searched:
            if node == end:       # 找到目标返回父节点列表,用以追溯最终路径
                return node, parents
            else:
                searched.append(node)       # 更新已搜索列表
                for n in graph[node]:       # 记录达到节点的最近路径的父节点
                    if not parents[n]:
                        parents[n] = node
                    search_queue.append(n)      # 邻居节点入队
    return False

路径追溯

def find_start(parents, key):
    res = []
    while parents[key] != 'start':
        res.append(key)
        key = parents[key]
    res.append(key)
    res.append("start")
    res.reverse()

    for i in res:
        if i == 'fin':
            print(i)
        else:
            print(i, "-->", end='')

目标:查找从“start”–>“fin”的最短路径

def main():
    # 创建路径图和父节点散列表
    graphTable = creat_graph()
    parents = parents_table()
    item, parentsTable = BFS(graphTable, 'start', 'fin', parents)
    # 最终路径追溯
    find_start(parentsTable, 'fin')


if __name__ == '__main__':
    main()

运行结果
BFS最短路径记录问题的解决(python)_第1张图片

你可能感兴趣的:(BFS,Python)