廣度優先搜尋的一些學習筆記
阿新 • • 發佈:2018-12-16
圖
什麼是圖?
圖由節點和邊組成。一個節點可能與眾多節點直接相連,這些節點也被稱為鄰居。
圖用於模擬一組連線。
例如從雙子峰到金門大橋的出行路線圖:
由上面這個圖,我們要找出從雙子峰到金門大橋的最短換乘路線,這個問題被稱為最短路徑問題,而解決最短路徑問題的演算法被稱為廣度優先搜尋。
廣度優先搜尋
廣度優先搜尋是一種用於圖的查詢演算法。
它可用於解決兩類問題:
1、從某節點出發,有去往下一節點的路徑嗎?
2、從某節點出發,前往下一節點的哪條路徑最短?
想要實現廣度優先搜尋首先我們要解決優先順序的實現問題,很顯然,在這裡使用佇列是很明智的選擇。
然後我們需要實現圖,圖由多個節點組成,很顯然,在這裡我們可以使用散列表
執行時間
將一個元素新增到佇列需要的時間是固定的,為O(1),因此對每個元素都這樣做需要的總時間為O(元素個數),在圖裡面從一個節點到另一個節點需要的時間是O(邊數)。所以廣度優先搜尋的執行時間為O(元素個數 + 邊數),這通常寫作O(V + E),其中V為頂點數,E為邊數。
樹是一種特殊的圖,其中沒有往後指的邊。
程式碼
這裡以經營芒果農場需要將芒果賣給芒果銷售商為例,我們需要通過Facebook去查詢芒果銷售商:
# 首先建立表示人際關係的圖 graph = {} graph['you'] = ['alice', 'bob', 'claire'] graph['bob'] = ['angel', 'peggy'] graph['alice'] = ['peggy'] graph['claire'] = ['tom', 'jonny'] graph['angel'] = [] graph['peggy'] = [] graph['tom'] = [] graph['jonny'] = [] # 然後建立一個佇列,我們可以使用雙端佇列deque from collections import deque def search_mango(name): search_queue = deque() # 將‘你’的鄰居都加入到這個搜尋隊列中 search_queue += graph['you'] # 建立一個數組用於記錄檢查過的人 searched = [] # 只要佇列不為空,就取出其中的第一個人 while search_queue: person = search_queue.popleft() # 檢查這個人是否是芒果銷售商,函式person_is_seller可以自己嘗試去實現一下 if person not in searched: # 僅當這個人沒被檢查過時才檢查 if person_is_seller(person): print(person + "is a mango seller!") return True else: # 否則將這個人的朋友都加入到搜尋隊列 search_queue += graph[person] # 並將這個人標記為已被檢查過 searched.append(person) # 如果佇列中沒有人是芒果銷售商 return False search('you')