python实现图的广度优先搜素算法并打印最短路径

from collections import deque


def create_graph():
    """采用邻接表方式储存图"""
    graph = {}
    graph['A'] = ['B', 'C']
    graph['B'] = ['D']
    graph['C'] = ['E']
    graph['D'] = []
    graph['E'] = ['D']
    return graph


def search(graph, start, target):
    """
    广度优先搜索,从stat起始到target是否有路径,并打印最短路径
    :param graph: 图
    :param start: 起始点
    :param target: 目标点
    :return: 是否存在
    """
    print("start :" + start)

    # 创建一个队列用于广度优先搜索
    search_queue = deque()
    search_queue += graph[start]

    # 记录已经被检查的节点(防止闭环,死循环)
    searched = [start]

    # 如果队列为空,则该图中没有target
    while search_queue:
        # 先从队列中取出一个节点
        point = search_queue.popleft()
        # 该节点如果没被查找过,则进行检查
        if point not in searched:
            # 如果该节点,为target,则找到并打印最短路径
            if point == target:
                print("search :" + point)
                searched.append(point)
                # 打印最短路径
                path = get_path(searched, graph)
                print(" ".join(path))
                return True
            # 如果当前节点不是target,则把其邻居入队并把该节点加入被检查列表中
            else:
                search_queue += graph[point]
                searched.append(point)
    print("not searched")
    return False


def get_path(searched_list, graph):
    """
    打印最短路径(回溯法)
    思路:从target往上回溯,
    (1)判断当前节点是否为起始点,否则走(2),是则(4)
    (2)循环被检查点列表并寻找第一个为当前节点的父节点,
    (3)将父节点置为当前节点并结束本次寻找,重新走(2)
    (4)逆序列表则为最短路径
    """
    print("searched: " + str(searched_list))
    target = searched_list[-1]
    path = [target]
    while target != searched_list[0]:
        for i in searched_list:
            if target in graph[i]:
                target = i
                path.append(i)
                break
    return path[::-1]


if __name__ == '__main__':
    graph = create_graph()
    search(graph, 'A', 'E')

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章