1. 程式人生 > >python自然語言處理-廣度優先搜尋

python自然語言處理-廣度優先搜尋

一.概念

    在前面的例子中,我們建立了收集從凱文.貝肯開始的維基百科詞條連結的爬蟲,最後儲存在資料庫裡。這個遊戲體現了一種從一個頁面指向另一個頁面的連結路徑選擇問題。這個上篇文章找出一個單詞到另一個單詞的路徑問題是一樣的。這類問題被稱為有向圖(direct graph)問題,其中A-->B連通,並不意味著B-->A同樣連通。單詞“football”後面經常跟著“player”,但是單詞“player”後面卻很少跟著“football”。雖然“凱文貝肯”的維基百科詞條連線到他的老家費城(Philadelphia),但是費城的維基百科詞條裡卻沒有連線到他的連線。

    相反,原來的凱文貝肯六度分割遊戲是一個無向圖(undirected graph)問題。例如,凱文貝肯和茱莉亞羅伯茨(Julia Roberts)共同演過電影《別闖陰陽界》(Flatliners,1990),因此,凱文貝肯詞條通過《別闖陰陽界》的維基百科詞條會連線到茱莉亞羅伯茨詞條,而茱莉亞羅伯茨也會通過《別闖陰陽界》連線到凱文貝肯詞條,兩者的關係是相互的(也就是沒有方向性)。在電腦科學中,無向圖問題比有向圖問題不太常見,兩者都屬於計算難題。

  雖然解決這兩類問題和對應的多個分支問題的方法有很多,但是在尋找有向圖的最短路徑問題中,即找出維基百科中凱文貝肯詞條和其他詞條之間最短路徑的方法中,效果最好且最常用的一種方法就是廣度搜索演算法(breadth-first search)。

   廣度優先搜尋演算法的思路就是優先搜尋直接連線到起始頁的所有連結(而不是找到一個連結就縱向深入搜尋)。如果這些連結不包含目標頁面(你想要找到詞條),就對第二層的連結-連線到起始頁的頁面的所有連結--進行搜尋。這個過程不斷重複,知道達到搜尋深度限制(本例中使用的層數限制是6)或者找到目標頁面為止。

二.例項

   用前面獲得的連結資料表,實現一個廣度有限搜尋演算法,程式碼如下:

empty
   上述程式碼中函式getLinks和constructDict()是輔助函式,用來從資料庫裡獲取給定頁面的連結,然後把連結轉換成字典。主函式searchDepth會遞迴執行,同時構建和搜尋連結樹,一次搜尋一層。其執行規則如下:
  • 如果遞迴限制已經到達(即程式已經呼叫過很多次),就停止搜尋,返回結果;
  • 如果函式獲取的連結字典是空,就對當前頁面的連結進行搜尋。如果當前頁面也沒有連結,就返回空連結字典
  • 如果當前頁面包含我們搜尋的頁面連結,就把頁面ID複製到遞迴的棧頂,然後丟擲一個異常,顯示頁面已經找到。遞迴過程會打印出當前的頁面ID,然後後丟擲異常顯示頁面已經找到,最終列印在螢幕上的就是一個完整的額ID路徑列表。
  • 如果連結沒有找到,把遞迴限制減一,然後呼叫函式搜尋下一層連結。