迷宮系列(三)利用BFS/DFS的資料得到最短路/通路

小聲逼逼發表於2017-12-16

一、如何得到最短路

演算法性質分析

1.BFS性質:

該演算法需要在發現所有與這個源節點距離為k的節點後,才回去發現與這個源節點距離為k+1的節點。

故BFS對一個圖G的搜尋是嚴格分層的,如果一個點V在第n層被發現,那麼它距離源節點的最短距離一定為n,否則將違背BFS演算法的性質。

2.DFS性質:

主要思想:一條路走到黑
故:DFS在問題有解的情況下可以順利找到解,但DFS的搜尋是盲目的,它的目的僅僅是走過各種可能的分支來找到問題的解,但不一定是最優解。
比如:DFS演算法第一步就走了錯誤的一步,在此之後即使到達目的節點也不會是最短的路徑

3.結論

BFS演算法可以用來找出一個圖中的最短路
DFS演算法不能找出最短路,但可以找出所有通路(雖然BFS也可以)

二、如何得到路徑

1.考慮在BFS演算法示例中得到的結果

f
fd

假設起點為A,前往G,顯然最短路有兩條A->D->G和A->E->G

2.如何根據表格裡的資料得到路徑呢

h

思路1.

從起點A開始搜尋,根據dis遞增的規律來找到G,從而輸出正確的路徑
分析:不可行
原因:從A點出發會產生過多的旁枝,沒有意義

思路2.

從終點G開始逆向搜尋,根據dis遞減的規律來找到A,從而輸出正確的路徑
分析:可行
原因:由於起點是唯一的,從G延展出的所有dis嚴格遞減的節點序列最終一定都回到起點A。

3.如何實現?

做法:搜尋,深度優先搜尋= ̄ω ̄=

虛擬碼

PATH(節點v)
{
  if (v == 起點)
  {
    從棧底輸出棧S,即為最短路徑之一;
  }
  else
  {
    for (與v鄰接的每一個元素u)
    {
      if (u尚未被訪問)
      {
        if ( u.dis == v.dis - 1)  // u是v的前驅(是u發現的v)
        {
          標記u被訪問;
          把u壓入棧;
          PATH(u);
          取消u的標記;
          彈出棧頂元素;
        }
      }
    }
  }
}

另:如何尋找通路

對於通路,我們可以認為只要該節點dis屬性不為初始值(-1),這個節點就是可以行走的,所以我們可以從終點起,按照這樣的狀態轉移約束,搜尋出所有的通路

下一節將講解其他的實現細節和DFS的實際應用(敲黑板!重要!= ̄ω ̄=)

相關文章