1. 程式人生 > >python-廣度優先搜索

python-廣度優先搜索

這一 pen 不為 return pytho 什麽 時間 隊列 src

 廣度優先搜索

下面我們來來BFS算法策略:

 技術分享

  比如:我們要從雙子峰---->金門大橋,最短路徑如何?

  我們利用廣度優先搜索來一步步求解,註意廣度優先搜索在於的關鍵在於“廣”,也就是說以雙子峰為起點,我們要盡可能的多比較與之相鄰的周邊路徑,從其中選取一條最優路徑。

  第一步:

  技術分享

我們沿著兩個箭頭方向路徑探索到a點和b點後,發現並沒有到達想要去的地方,於是我繼續往下探索。

  技術分享

同樣,我們發現還沒有到達目的地,繼續往下探索。

  技術分享

  到達這一步後,我們發現其中有一條路徑已經到達金門大橋,而其他兩條路徑僅僅到達c點。因此,我們尋找到的最短路徑為:雙子峰->a->c->金門大橋。

  所以,由上我們可以知道,廣度優先搜索其實就是用來探索最短路徑的一種方式。

  根據上面實例,我們想要尋找一條到某地的最短路徑,需要一下兩個步驟:

    (1)使用圖來建立問題模型。

    (2)使用廣度優先搜索解決問題。

  利用廣度優先搜索,我們可以回答兩個問題:

    1.從節點A出發,有前往B節點的路徑嗎?

    2.從節點A出發,前往B節點哪條路徑最短?

 首先,我們來看看如何構建一張圖。

  這裏我們要使用一種能夠表示映射關系的數據結構---散列表。至於什麽是散列表,這裏就不再贅述。

  例如:

    技術分享

    graph = {}

    grapu[‘you‘] = [‘alice‘,‘bob‘,‘mar‘,‘rain‘,‘cat‘]

    這裏的“you”被映射到一個數組。在‘you‘的這個數組裏面,包含所有與你相鄰的元素。

    有了以上方式,我們就可以構建一張更大圖。

 算法實現策略:

    技術分享

   首先,創建一個雙端隊列,將需要查找的壓入隊列中。

   from collections import deque

   def person_is_seller(name):

      return name[-1] == ‘m‘ #如果這個名字是以M結尾,則是

   graph = {}

   grapu[‘you‘] = [‘alice‘,‘bob‘,‘mar‘,‘rain‘,‘cat‘]

   search_queue = deque() #創建一個隊列

   search_queue += graph[‘you‘] #將you壓入隊列

   while search_queue: #只要隊列不為空

      person = search_queue.popleft() #取出左邊第一個人

      if person_is_seller(person): #檢查這個人是否為芒果商

        print person += ‘ is a mango seller! ‘

        return True

      else:

        search_queue += graph[person] #將這個人的朋友加入隊列

      return False #沒有芒果商  

   但是,上面算法有一個明顯的問題,如果你的朋友alice和bob都有這一個好友,那麽在查找的過程中就會陷入循環狀態。要解決這個問題,我們可以設置一個列表,來標記那些已經被查找過的人。因此,最終代碼如下:

      def search(name):

        search_queue = deque() #創建一個隊列

        search_queue += graph[name] #將需要查找的壓入隊列

    searcher = [] # 用於記錄已經查找過的

        while search_queue: #只要隊列不為空

            person = search_queue.popleft() #取出左邊第一個人

            if not person in searched: #當這個人不在searched中才繼續往下查找

              if person_is_seller(person): #檢查這個人是否為芒果商

                print person += ‘ is a mango seller! ‘

                return True

              else:

                search_queue += graph[person] #將這個人的朋友加入隊列

                searched.append(person)

        return False #沒有芒果商 

 性能分析:

    首先沿著每條邊進行查找,如果邊數為n,查找效率為O(V)

    再次,我們在每次查找過程中需要對已經搜索的列表進行二次判斷,判斷所需時間為P(n)

    因此,廣度優先搜索總的查找效率為O(V+n)

  

python-廣度優先搜索