上回說到,如何確定最大匹配數。接下來,本次將簡述如何確定最優匹配路徑。仿照確定最大匹配數的演算法,這個問題也非常容易解決,不知道這周當中,有沒有哪位 xdjm
已經有了自己的解決方案呢?
有問題可以發郵件給我:
文字比較演算法剖析( 2)
-如何確定最優匹配路徑
確定最優匹配路徑的問題,通常在做檔案比較時要用到,它的意思是:在所有能夠得到最大匹配點數的路徑中,找出一條最短的路徑。
讓我們繼續以上次的例子進行研究:
首先,我們仍然是手工標出能夠得到最大匹配點數的所有路徑。在手工繪製可用路徑的時候,需要說明一下: l
首先,這裡我們以計算 left
的最優路徑為例。計算 right
的最優路徑和 left
是完全對稱的; l
在圖中,向右移動一格,表示 left
的當前元素放棄和 right
的當前元素進行匹配,而和 right
的下乙個元素進行匹配。如果進行檔案比較的話,就是 left
檔案的當前行前,插入 right
檔案的當前行; l
在圖中,向下移動一格,表示 left
的當前元素放棄和 right
的當前元素進行匹配,而使用 left
的下乙個元素和 right
的當前元素進行匹配。如果進行檔案比較的話,就是 left
檔案的當前行被刪除; l
在途中,向右下方移動一格,表示確定 left
和 right
的當前元素的匹配,使用 left
的下乙個元素和 right
的下乙個元素進行匹配。如果進行檔案比較的話,就是 left
和 right
檔案的當前行已經匹配,分別比較下一行。 l
由於 left
和 right
是流式的,所以每個元素只能匹配一次而且不能顛倒順序,所以,在 x
和 y方向上,只能保留乙個匹配點,而且只能向下,向右,或者向右下方移動。
有了這些規則,我們就可以得到如下圖中間紅色粗線所示的 4
條可能的路徑。
從上向下,依次編號為 1,2,3,4
號路徑,分析如下: 1
號路徑表示(只說明含義,演算法推導在後面):
依次類推,可以得到其他路徑的實際含義。需要說明的是, 3
號路徑在選擇第二個匹配點時,沒有採用 left[9]:right[1]
的匹配關係,而是跳過 left[9]
,採用了 left[11]:right[1]
。這樣,點 (left[9], right[1])
在 3號路徑上是「刪除 left
第 9行」的意思。
如果我將整個過程中在 left
上移動的距離紀錄下來,就得到:
從圖上就很容易看出,在 left
上移動最短的,也就是最優的路徑,是 4
號路徑。
是不是看起來毫無頭緒?
別急,象上次一樣,我們進行乙個分析。
依然是歸納法,依然是找出元素 d(l,r)
的 3個相鄰區域 a,b,c:
分析: 1.
如果點 d(l,r)
表示從 left
的第 l
個元素, right
的第 r
個元素出發,匹配到矩陣邊界後,在 left
方向上的最短路徑長度 (我更喜歡稱之為 depth ) ,那麼: 2.
如果點 (l,r)
是乙個被確定的匹配點,那麼下一步,只能選擇進入 a
區域,到點 (l+1,r+1)
,所以得到:
d1
if (v(l,r)>0) then d(l,r) = 1 + d(l+1,r+1)
還記得 v(l,r)
和 n(l,r)
的定義麼?可以看看文件《文字比較演算法剖析(1
) -
如何確定最大匹配率》 3.
如果點 (l,r)
不是乙個被確定的匹配點,那麼下一步可以進入 b
或者 c.
d2
如果進入 b
區域,那麼意味著 」
插入 right
的第 r
行 」,但是在 left
的位置保持不變,所以得到:
if (v(l,r) == 0) then d(l,r) = d(l,r+1)
d3
如果進入 c
區域,那麼意味著 」
刪除 left
的第 l
行 」,在 right
的位置保持不變,但是在 left
的位置要加 1
。所以得到
:if (v(l,r) == 0) then d(l,r) = 1 + d(l+1,r)
那麼現在有 3
個值 d1
, d2 , d3 ,該如何取捨呢?直接取 min(d1,d2,d3) 可以麼?
呵呵,其實,我也是嘗試了很多次以後才搞清楚的。大家可以用 excel 驗證一下自己的想法。很簡單的,大概驗證整個演算法,用 10 行左右的**再加上 excel 本身提供的公式就足夠了。
4.
不要忘記了前面說過的, 」
在所有能夠得到最大匹配點數的路徑中,找出一條最短的路徑 」,
首先我們要保證得到最大匹配匹配點數,所以我們又有:
if (n(l,r+1) >= n (l+1,r) then
d(l,r) = d(l,r+1);
else
d(l+r) = 1 + d(l+1,r)
綜合上面所有的分析,路徑長度 d(l,r) 的計算公式就是:
if (v(l,r) = 1) then
d(l,r) = d(l+1,r+1) + 1
else
if (n(l,r+1) >= n(l+1,r)) then
d(l,r) = d(l,r+1)
else
d(l,r) = d(l+1,r) + 1
end if
將公式寫入 excel 自動計算,得到結果如圖:
可以看到,結果正確。
ok 。 結束了,文字比較的演算法核心就介紹完了。
事實上,上面第四步給出的是優化後的結果,有興趣的可以自己試著分析一下第 4 步是否應該這樣計算,有什麼情況我沒有在這裡講的,但是結果為什麼又是正確的。
有了這個演算法,大家可以很快的編寫自己的文字比較功能了。
計算最優路徑的附加時間複雜度為 0 ,因為它完全可以和計算最大匹配點數一起進行;附加的空間複雜度為 max(m,n), 因為它需要乙個額外的陣列紀錄 n(l+1) 。
如果不計算最優路徑的話,計算最大匹配點數的演算法還可以再優化。
注1: 感謝jcodeer.chang,為我糾正了文中的表示式的錯誤。
《轉》文字比較演算法剖析(1) 如何確定最大匹配率
最近看到有人在找關於文字比較的演算法,剛好最近休假,研究了一下,終於找到乙個簡單有效的演算法,和大家分享一下。演算法本身很簡單,但是要說清楚思路和原理就比較複雜了,打算分兩次發表 明天就要上班拉!分別對應文字比較演算法中的兩個主要問題 1。如何確定最大匹配率 2。如何確定最優的匹配路徑 演算法本身是...
文字比較演算法剖析(1) 如何確定最大匹配率
最近看到有人在找關於文字比較的演算法,剛好最近休假,研究了一下,終於找到乙個簡單有效的演算法,和大家分享一下。演算法本身很簡單,但是要說清楚思路和原理就比較複雜了,打算分兩次發表 明天就要上班拉!分別對應文字比較演算法中的兩個主要問題 1。如何確定最大匹配率 2。如何確定最優的匹配路徑 文字比較演算...
文字比較演算法 Nakatsu演算法
在 文字比較演算法 ld演算法 文字比較演算法 needleman wunsch演算法 中介紹的ld演算法和lcs演算法都是基於動態規劃的。它們的時間複雜度o mn 空間複雜度o mn 在基於計算匹配字串情況下,是不可優化的。如果只是計算ld和lcs,空間占用可以優化到o m nakatsu演算法在...