一.概念
在前面的例子中,我們創建了收集從凱文.貝肯開始的維基百科詞條鏈接的爬蟲,最後存儲在數據庫裏。這個遊戲體現了一種從一個頁面指向另一個頁面的鏈接路徑選擇問題。這個上篇文章找出一個單詞到另一個單詞的路徑問題是一樣的。這類問題被稱爲有向圖(direct graph)問題,其中A-->B連通,並不意味着B-->A同樣連通。單詞“football”後面經常跟着“player”,但是單詞“player”後面卻很少跟着“football”。雖然“凱文貝肯”的維基百科詞條連接到他的老家費城(Philadelphia),但是費城的維基百科詞條裏卻沒有連接到他的連接。
相反,原來的凱文貝肯六度分割遊戲是一個無向圖(undirected graph)問題。例如,凱文貝肯和茱莉亞羅伯茨(Julia Roberts)共同演過電影《別闖陰陽界》(Flatliners,1990),因此,凱文貝肯詞條通過《別闖陰陽界》的維基百科詞條會連接到茱莉亞羅伯茨詞條,而茱莉亞羅伯茨也會通過《別闖陰陽界》連接到凱文貝肯詞條,兩者的關係是相互的(也就是沒有方向性)。在計算機科學中,無向圖問題比有向圖問題不太常見,兩者都屬於計算難題。
雖然解決這兩類問題和對應的多個分支問題的方法有很多,但是在尋找有向圖的最短路徑問題中,即找出維基百科中凱文貝肯詞條和其他詞條之間最短路徑的方法中,效果最好且最常用的一種方法就是廣度搜索算法(breadth-first search)。
廣度優先搜索算法的思路就是優先搜尋直接連接到起始頁的所有鏈接(而不是找到一個鏈接就縱向深入搜索)。如果這些鏈接不包含目標頁面(你想要找到詞條),就對第二層的鏈接-連接到起始頁的頁面的所有鏈接--進行搜索。這個過程不斷重複,知道達到搜索深度限制(本例中使用的層數限制是6)或者找到目標頁面爲止。
二.實例
用前面獲得的鏈接數據表,實現一個廣度有限搜索算法,代碼如下:
empty
- 如果遞歸限制已經到達(即程序已經調用過很多次),就停止搜索,返回結果;
- 如果函數獲取的鏈接字典是空,就對當前頁面的鏈接進行搜索。如果當前頁面也沒有鏈接,就返回空鏈接字典
- 如果當前頁面包含我們搜索的頁面鏈接,就把頁面ID複製到遞歸的棧頂,然後拋出一個異常,顯示頁面已經找到。遞歸過程會打印出當前的頁面ID,然後後拋出異常顯示頁面已經找到,最終打印在屏幕上的就是一個完整的額ID路徑列表。
- 如果鏈接沒有找到,把遞歸限制減一,然後調用函數搜索下一層鏈接。