算法與數據結構(1) : [python] 廣度優先搜索

參考 : https://blog.csdn.net/qq_38003892/article/details/103222003

定義

    寬度優先搜索算法(又稱廣度優先搜索)是最簡便的圖的搜索算法之一,這一算法也是很多重要的圖的算法的原型。Dijkstra單源最短路徑算法和Prim最小生成樹算法都採用了和寬度優先搜索類似的思想。其別名又叫BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜索整張圖,直到找到結果爲止。(來自百度百科)

使用場景

廣度優先搜索讓你能夠找出兩樣東西之間的最短距離,不過最短距離的含義有很多!使用廣 度優先搜索可以:

  •   編寫國際跳棋AI,計算最少走多少步就可獲勝;

  •   編寫拼寫檢查器,計算最少編輯多少個地方就可將錯拼的單詞改成正確的單詞,如將

    READED改爲READER需要編輯一個地方;

  •   根據你的人際關係網絡找到關係最近的醫生。(來自[圖解算法])

實現

在下面有向圖中找出A點到L點的最短路徑

 

用到的數據結構:

  • 隊列
  • 列表(數組、鏈表)
  • 字典(散列表)

Python代碼如下:

# -*- coding:utf-8 -*-
from collections import deque


def init_graph():
    """
    表示一個有向圖
    :return:
    """
    graph = dict()
    graph['A'] = ['B', 'D', 'E']
    graph['B'] = ['C', 'E']
    graph['C'] = ['F']
    graph['D'] = ['E', 'G']
    graph['E'] = ['F', 'H']
    graph['F'] = ['I']
    graph['G'] = ['H', 'J']
    graph['H'] = ['I', 'K', 'L']
    graph['I'] = ['L']
    graph['J'] = ['K']
    graph['K'] = ['L']
    graph['L'] = []
    return graph


def search(graph, start, target):
    # 檢索隊列
    search_queue = deque()
    search_queue += graph[start]
    # 把起點的子節點加入隊列
    searched = [start]
    while search_queue:
        # 取出隊列的第一個節點
        left = search_queue.popleft()
        # 是否已檢索
        if left not in searched:
            if left == target:
                searched.append(left)
                print('->'.join(append_path(searched, graph)))
                break
            else:
                # 把改節點的子節點加入隊列
                search_queue += graph[left]
                # 把該節點標記爲已檢索
                searched.append(left)


def append_path(searched, graph):
    """
    1.取出已檢索的節點集合的最後一個節點
    2.遍歷已檢索的節點集合,根據檢索順序找出第一個子節點含有最後一個節點的節點,把該節點定義爲最後節點的父節點
    3.再次遍歷已檢索的節點集合,檢索上步驟找到的節點,尋找第一個子節點含有該節點的接口,重複此操作直至找到的父節點爲起點

    :param searched: 已檢索的節點集合
    :param graph: 圖
    :return:
    """
    target = searched[-1]
    path = [target]
    while target != searched[0]:
        for i in searched:
            if target in graph[i]:
                target = i
                path.append(i)
                break
    return path[::-1]


if __name__ == '__main__':
    graphs = init_graph()
    search(graphs, 'A', 'L')

 

 

END。

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