解決最短路徑問題的算法被稱為廣度優先(breadth-first search,BFS)搜索。
廣度優先搜索是一種用於圖的查找算法,可解決兩類問題:
從節點A出發,有前往節點B的路徑嗎?
從節點A出發,前往節點B的哪條路徑最短?
最短路徑問題的解決步驟:
1.使用圖建立問題模型;
圖用於模擬不同的東西是如何相連的。
2.使用廣度優先搜索解決問題。
廣度優先搜素算法從鄰居節點及鄰近節點的鄰居節點中搜索,直到搜索到目標。
首先搜索一度 關系,再搜索二度關系 ,然后三度關系,......
因此,廣度優先搜索不僅查到從A到B的路徑,而且找到的是最短的路徑。
只有按添加順序查找時,才能實現這樣的目的;可以使用隊列(queue)來實現。
隊列工作原理:先進先出(First In First Out,FIFO)。
隊列操作:入隊,出隊。
圖的實現:
圖由一系列的節點和邊組成;每個節點都與鄰近節點相連,可以使用散列表來實現圖。
散列表是無序的,添加鍵-值對的順序是無關的。
1.圖的表示(每個節點都與鄰近節點 相連,散列表)
2.算法實現
from collections import deque
graph = {}
graph["you"] = {"alice", "bob", "claire"}
# 一度關系
graph["alice"] = ["peggy"]
graph["bob"] = ["anuj", "peggy"]
graph["claire"] = ["thom","jonny"]
# 二度關系
graph["peggy"] = []
graph["anuj"] = []
graph["thom"] = []
graph["jonny"] = []
# 判斷name是否以m結尾
def person_is_seller(name):
return name[-1] == 'm'
# breadth-first-search(BFS)
def search(name):
search_queue = deque() # 創建隊列
search_queue += graph[name] # 將鄰近加入到創建的搜索隊列中
searched = [] # 記錄搜索過的人,防止形成無限循環
while search_queue:
person = search_queue.popleft() # 出隊
if person not in searched: # 是否位目標
if person_is_seller(person):
print("%s is a seller" %(person))
else:
search_queue += graph[person] # 不是,將鄰近加入到搜索隊列
searched.append(person) # 加入到已經搜索過的列表
return False
if __name__ == '__main__':
search("you")