超酷算法-BK樹


前幾天無意間遇到一個博客,覺得寫得挺好的,自己之前的時候有個不好的習慣,那就是遇到了好資源第一反應就是收藏起來然后卻很少再看!!這是壞習慣,要改!於是今天就開始通讀了,讀的第二篇是BK樹。覺得有點意思,於是乎就萌發了寫個博客啥的,但是呢,我發現已經有人翻譯了。那還干嘛重復發明輪子呢,鑒於原作者聲明禁止轉載,那就算了吧,想看原文的來這里

下面簡單說明一下這個算法,確實不難,只是思路有點巧妙。

BK樹解決一個什么問題呢,簡單而言就是找相似字符串,比如說"book"跟"boon"是不是只差一個字母,很相似了吧。

我們先來定義相似:采用編輯距離來度量兩個字符串之間的相似程度。字符串A和字符串B的編輯距離就是至少需要幾次操作(刪除一個字母,插入一個字母,更換一個字母)才能使得A變成B。上面提到的"book"以及"boon"的編輯距離就是1,因為只需要將字母'k'更新為'n'就可以達到目的了。

接下來我們來看編輯距離的一個性質,我們用L(A,B)來表示字符串A和字符串B之間的編輯距離。那么我們為了找到與A距離不超過m的字符串C,那么它與字符串B的距離為多少呢?答案是L(A,B)-m <= L(B,C) <= L(A,B)+m。為什么?m步之內A、C可以相互轉換,而L(B,C)步之內B、C可以相互轉換,於是乎m+L(B,C)步之內,A、B之間必然可以轉換,於是有L(A,B) <= L(B,C)+m;同理可知 L(B,C) <= L(A,B)+m。

那么這樣一來的話,BK樹就可以出場了。BK樹的邊是有編號的,編號值就是邊的兩個節點直接的編輯距離。

我們先在字符串集合中任選一個字符串Z作為根節點,然后每次從集合中取出一個字符串X,將其插入樹中。插入規則是這樣的,首先計算X與根節點Z的編輯距離L(X,Z),然后將這個節點插入到Z的編號為L(X,Z)的孩子那邊;遞歸直到到達X可以成為葉子節點。

我們查找字符串A的相似字符串的時候(假設編輯距離為2以內就算相似),那么從根節點開始尋找,先計算L(Z,A),這個時候我們就知道了與A編輯距離為2的字符串只可能存在於Z的編號為L(Z,A)-2到編號為L(Z,A)+2之間的那些子樹里面,於是乎就遞歸查找去吧。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM