1. 程式人生 > >Python3&資料結構之廣度優先搜尋(Breadth First Search,BFS)

Python3&資料結構之廣度優先搜尋(Breadth First Search,BFS)

說到BFS,首先要介紹圖

什麼是圖?圖模擬一組連結,由節點和邊組成

圖分為有向圖(directed graph)和無向圖(undirected graph)

有向圖中的關係是單向的,所以可以由箭頭表示

無向圖中直接相連的節點互為鄰居,所以沒有箭頭

參考演算法圖解,例如,下面兩個圖是等價的。

那麼廣度優先搜尋有什麼用呢?它可以幫助回答下面兩類問題:

  • 從節點A出發,有前往節點B的路徑嗎?
  • 從節點A出發,前往節點B的哪條路徑最短

不過要想實現BFS,不僅要了解什麼是圖,還要了解佇列(queue)這種資料結構

佇列只有兩種操作:入隊和出隊

佇列是一種先進先出(First In First out,,FIFO)的資料結構,而棧是一種後進先出(Last In First Out,LIFO)的資料結構

 

我們的目的是在由這8個人組成的關係網中找到芒果銷售商,那麼誰是芒果銷售商呢,假設人的姓名是否以m結尾:如果是,他就是芒果銷售商,很明顯圖中就是Thom,接下由程式碼來實現它。

接下來是程式碼部分:

首先是實現圖的程式碼,它是由散列表來實現的,在python中由字典來表現這種資料結構

graph = {}
graph['you'] = ['alice','bob','claire']
graph['bob'] = ['anuj','peggy']
graph['alice'] = ['peggy']
graph['claire'] = ['thom','jonny']
graph['anuj'] = []
graph['peggy'] = []
graph['thom'] = []
graph['jonny'] = []

print(graph)

然後是實現佇列的程式碼

from collections import deque
search_queue = deque()    #建立一個佇列
search_queue += graph['you']
print(search_queue)

最後是演算法的工作原理以及完整的BFS程式碼

#BFS
from collections import deque

graph = {}
graph['you'] = ['alice','bob','claire']
graph['bob'] = ['anuj','peggy']
graph['alice'] = ['peggy']
graph['claire'] = ['thom','jonny']
graph['anuj'] = []
graph['peggy'] = []
graph['thom'] = []
graph['jonny'] = []

def BFS(name):
    search_queue = deque()
    search_queue += graph[name]
    searched = []
    while search_queue:
        person = search_queue.popleft()
        if not person 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

def person_is_seller(name):
    return name[-1] == 'm'

if __name__ == '__main__':
    BFS('you')