廣度優先搜索 - 寬度優先搜索 - 橫向優先搜索 (breadth-first search,BFS)

廣度優先搜索 - 寬度優先搜索 - 橫向優先搜索 (breadth-first search,BFS)

1. 廣度優先搜索 - 寬度優先搜索 - 橫向優先搜索 (breadth-first search,BFS)

depth-first search,DFS:深度優先搜索
breadth-first search,BFS:廣度優先搜索

Breadth-first search (BFS) is an algorithm for traversing or searching tree or graph data structures. It starts at the tree root (or some arbitrary node of a graph, sometimes referred to as a search key), and explores all of the neighbor nodes at the present depth prior to moving on to the nodes at the next depth level.
廣度優先搜索 (BFS) 是用於遍歷或搜索樹或圖形數據結構的算法。它從樹的根部 (或圖的某個任意節點,有時稱爲搜索關鍵字) 開始,並在移至下一個深度級別的節點之前先探索當前深度的所有鄰居節點。

廣度優先搜索 - 寬度優先搜索 - 橫向優先搜索 (breadth-first search,BFS) 是一種圖形搜索算法。BFS 是從根節點開始,沿着樹的寬度遍歷樹的節點。如果所有節點均被訪問,則算法中止。廣度優先搜索的實現一般採用 open-closed 表。

It uses the opposite strategy as depth-first search, which instead explores the node branch as far as possible before being forced to backtrack and expand other nodes.
它使用與深度優先搜索相反的策略,而是在被迫回溯和擴展其他節點之前,儘可能地探索節點分支。

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述
以德國城市爲示例的地圖。城市間有數條道路相連接。(An example map of Southern Germany with some connections between cities.)

在這裏插入圖片描述
從法蘭克福開始運行廣度優先搜索算法,所產生的廣度優先搜索算法樹。(The breadth-first tree obtained when running BFS on the given map and starting in Frankfurt.)

在這裏插入圖片描述
廣度優先搜索算法的動畫示例 (Animated example of a breadth-first search) - 達到覆蓋面積的作用

BFS 是一種盲目搜索法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。它並不考慮結果的可能地址,徹底地搜索整張圖,直到找到結果爲止。BFS 並不使用經驗法則算法。

從算法的觀點,所有因爲展開節點而得到的子節點都會被加進一個先進先出的隊列中。一般的實現裏,其鄰居節點尚未被檢驗過的節點會被放置在一個被稱爲 open 的容器中 (例如隊列或鏈表),而被檢驗過的節點則被放置在被稱爲 closed 的容器中。(open-closed 表)

animate [ˈænɪmeɪt]:vt. 使有生氣,使活潑,鼓舞,推動 adj. 有生命的

廣度優先搜索 (BFS) 是圖的一種遍歷方式,它以廣度優先進行搜索。簡言之就是先訪問圖的頂點,然後廣度優先訪問其鄰接點,然後再依次進行被訪問點的鄰接點,一層一層訪問,直至訪問完所有點,遍歷結束。

1.1 無向圖的廣度優先搜索過程

遍歷結果:A -> C -> D -> F -> B -> G -> E

在這裏插入圖片描述

1.2 有向圖的廣度優先搜索

遍歷結果:A -> B -> C -> E -> F -> D -> G

在這裏插入圖片描述

2. 深度優先搜索 - 廣度優先搜索

  • 深度優先搜索佔內存少但速度較慢,廣度優先搜索佔內存多但速度較快。
  • 深度優先搜索與廣度優先搜索的控制結構和產生系統很相似,唯一的區別在於對擴展節點選取上。
  • 深度優先搜索與廣度優先搜索兩種算法每次都擴展一個節點的所有子節點,不同的是,深度優先下一次擴展的是本次擴展出來的子節點中的一個,而廣度優先擴展的則是本次擴展的節點的兄弟點。在具體實現上爲了提高效率,所以採用了不同的數據結構。

2.1 深度優先搜索 (depth-first search,DFS)

深度優先搜索用棧 (stack) 來實現,整個過程可以看做一個倒立的樹形。

  1. 把根節點壓入棧中。
  2. 每次從棧中彈出一個元素,搜索所有在它下一級的元素,把這些元素壓入棧中。並把這個元素記爲它下一級元素的前驅。
  3. 找到所要找的元素時結束程序。
  4. 如果遍歷整個樹還沒有找到,結束程序。

2.2 廣度優先搜索 - 寬度優先搜索 - 橫向優先搜索 (breadth-first search,BFS)

廣度優先搜索使用隊列 (queue) 來實現,整個過程可以看做一個倒立的樹形。

  1. 把根節點放到隊列的末尾。
  2. 每次從隊列的頭部取出一個元素,查看這個元素所有的下一級元素,把它們放到隊列的末尾。並把這個元素記爲它下一級元素的前驅。
  3. 找到所要找的元素時結束程序。
  4. 如果遍歷整個樹還沒有找到,結束程序。

3. 空間複雜度

說法一
所有節點都必須被存儲,BFS 的空間複雜度爲 O(V+E)O(|V|+|E|),其中 V|V| 是節點的數目,而 E|E| 是圖中邊的數目。

說法二
BFS 的空間複雜度爲 O(BM)O(B^M),其中 BB 是最大分支系數,而 MM 是樹的最長路徑長度。由於對空間的大量需求,BFS 並不適合解非常大的問題。對於類似的問題,應用 IDDFS 以達節省空間的效果。

4. 時間複雜度

最差情形下,BFS 必須查找所有到可能節點的所有路徑,因此其時間複雜度爲 O(V+E)O(|V|+|E|),其中 V|V| 是節點的數目,而 E|E| 是圖中邊的數目。

5. 完全性

廣度優先搜索算法具有完全性。無論圖形的種類如何,只要目標存在,則 BFS 一定會找到。若目標不存在,且圖爲無限大,則 BFS 將不收斂 (不會結束)。

6. 最佳解

若所有邊的長度相等,廣度優先搜索算法是最佳解 - 亦即它找到的第一個解,距離根節點的邊數目一定最少。但對一般的圖來說,BFS 並不一定回傳最佳解。這是因爲當圖形爲加權圖 (亦即各邊長度不同) 時,BFS 仍然回傳從根節點開始,經過邊數目最少的解。而這個解距離根節點的距離不一定最短。這個問題可以使用考慮各邊權值,BFS 的改良算法成本一致搜索法來解決。若非加權圖形,則所有邊的長度相等,BFS 就能找到最近的最佳解。

7. 廣度優先搜索算法的應用

廣度優先搜索算法能用來解決圖論中的許多問題,例如:

  • 查找圖中所有連接組件 (Connected Component)。一個連接組件是圖中的最大相連子圖。
  • 查找連接組件中的所有節點。
  • 查找非加權圖中任兩點的最短路徑。
  • 測試一圖是否爲二分圖。
  • (Reverse) Cuthill-McKee 算法

7.1 查找連接組件

由起點開始,運行廣度優先搜索算法後所經過的所有節點,即爲包含起點的一個連接組件。

References

https://en.wikipedia.org/wiki/Breadth-first_search
https://en.wikipedia.org/wiki/Depth-first_search

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