python-廣度優先搜索
廣度優先搜索
下面我們來來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-廣度優先搜索