看到上面位址裡的乙個bk演算法,理解了半天……感覺演算法用來查詢不錯,記下來加上個人一些理解。
這是『超酷演算法』系列的第一篇文章。基本上,任何一種演算法我覺得都很酷,尤其是那些不那麼明顯簡單的演算法。
bk樹或者稱為burkhard-keller樹,是一種基於樹的資料結構,被設計於快速查詢近似字串匹配,比方說拼寫檢查器,或模糊查詢,當搜尋」aeek」時能返回」seek」和」peek」。為何bk-trees這麼酷,因為除了窮舉搜尋,沒有其他顯而易見的解決方法,並且它能以簡單和優雅的方法大幅度提公升搜尋速度。
現在我們觀察下編輯距離:構造乙個度量空間(metric space),該空間內任何關係滿足以下三條基本條件:
上述條件中的最後一條被叫做三角不等式(******** inequality)。三角不等式表明x到z的路徑不可能長於另乙個中間點的任何路徑(從x到y再到z)。看下三角形,你不可能從一點到另外一點的兩側再畫出一條比它更短的邊來。
編輯距離符合基於以上三條所構造的度量空間。請注意,有其它更為普遍的空間,比如歐幾里得空間(euclidian space),編輯距離不是歐幾里得的。既然我們了解了編輯距離(或者其它類似的字串距離函式)所表達的度量的空間,再來看下burkhard和keller所觀察到的關鍵結論。
假設現在我們有兩個引數,query表示我們搜尋的字串,n表示字串最大距離,我們可以拿任意字串test來跟query進行比較。呼叫距離函式得到距離d,因為我們知道三角不等式是成立的,所以所有結果與test的距離最大為d+n,最小為d-n。
由此,bk樹的構造就相當簡單:每個節點有任意個子節點,每條邊有個值表示編輯距離。所有子節點到父節點的邊上標註n表示編輯距離恰好為n。比如,我們有棵樹父節點是」book」和兩個子節點」rook」和」nooks」,」book」到」rook」的邊標號1,」book」到」nooks」的邊上標號2。
從字典裡構造好樹後,取任意單詞作為樹的根節點。無論何時你想插入新單詞時,計算該單詞與根節點的編輯距離,並且查詢數值為d(neweord, root)的邊。遞迴得與各子節點進行比較,直到沒有子節點,你就可以建立新的子節點並將新單詞儲存在那。比如,插入」boon」到剛才上述例子的樹中,我們先檢查根節點,查詢d(「book」, 「boon」) = 1的邊,然後檢查標號為1的邊的子節點,得到單詞」rook」。我們再計算距離d(「rook」, 「boon」)=2,則將新單詞插在」rook」之後,邊標號為2。
bk樹是多路查詢樹,並且是不規則的(但通常是平衡的)。試驗表明,1個查詢的搜尋距離不會超過樹的5-8%,並且2個錯誤查詢的搜尋距離不會超過樹的17-25%,這可比檢查每個節點改進了一大步啊!需要注意的是,如果要進行精確查詢,也可以非常有效地通過簡單地將n設定為0進行。
關於查詢我畫了個圖,幫助理解:
文中查詢說的不是很詳細,寫下自己理解的流程(有空程式設計實現):
step 1. query與根節點比較,編輯距離為d,然後找邊值在範圍(d-n,d+n)的子節點test(根據bk樹結構特點,不在此範圍代表這整個分支都不滿足查詢條件,可剪枝);
step 2. 然後比較query與test節點的編輯距離,如果小於n,代表找到test節點符合查詢要求,返回此節點;
step 3. 將當前的test節點當做根節點,返回step 1. 繼續查詢其子節點。遞迴以致遍歷bk樹,即可找到所有滿足條件的結果。
bk樹 編輯距離演算法
演算法出處 matrix67大神,除了字串匹配 查詢回文串 查詢重複子串等經典問題以外,日常生活中我們還會遇到其它一些怪異的字串問題。比如,有時我們需要知道給定的兩個字串 有多像 換句話說兩個字串的相似度是多少。1965年,科學家vladimir levenshtein給字串相似度做出了乙個明確的定...
《演算法》 3 3平衡查詢樹(1)
理想情況下如何保持二叉樹的平衡?這裡引入平衡查詢樹。2 3查詢樹定義 2 節點,含有乙個鍵 及其對應值 和兩條鏈結,左鏈結指向的節點的鍵小於該節點,右鏈結指向的節點的鍵大於該節點 3 節點,含有兩個鍵 及其對應值 和三條鏈結,左鏈結指向的節點的鍵都小於該節點,中鏈結指向的節點的鍵介於節點的兩個鍵之間...
AI演算法 1 決策樹
今天,我們介紹的機器學習演算法叫決策樹。跟之前一樣,介紹演算法之前先舉乙個案例,然後看一下如何用演算法去解決案例中的問題。我把案例簡述一下 某公司開發了一款遊戲,並且得到了一些使用者的資料。如下所示 圖上每個圖形表示乙個使用者,橫座標是年齡,縱座標是性別。紅色表示該使用者喜歡這款遊戲,藍色表示該使用...