1. 程式人生 > >廣度優先搜尋的一些學習筆記

廣度優先搜尋的一些學習筆記

什麼是圖?
圖由節點和邊組成。一個節點可能與眾多節點直接相連,這些節點也被稱為鄰居。
圖用於模擬一組連線。
例如從雙子峰到金門大橋的出行路線圖:
在這裡插入圖片描述

由上面這個圖,我們要找出從雙子峰到金門大橋的最短換乘路線,這個問題被稱為最短路徑問題,而解決最短路徑問題的演算法被稱為廣度優先搜尋。

廣度優先搜尋

廣度優先搜尋是一種用於圖的查詢演算法。

它可用於解決兩類問題:
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')