1. 程式人生 > >演算法:編輯距離問題(動態規劃)

演算法:編輯距離問題(動態規劃)

問題描述:

設A和B是2個字串。要用最少的字元操作將字串A轉換為字串B。這裡所說的字元操作包括(1)刪除一個字元; (2)插入一個字元; (3)將一個字元改為另一個字元。將字串A變換為字串B所用的最少字元運算元稱為字串A到 B的編輯距離,記為d(A,B)。對於給定的字串A和字串B,計算其編輯距離 d(A,B)。

個人對問題的理解:設兩個字串s[0:i],t[0:j],用最少的運算元(三種:增刪換,三種各花銷一次操作)將s變成t(或者t變成s,同等),先解決三種特殊情況

1)s為空,t不為空;

2)t為空,s不為空;

3)s與t相等;

對於第一第二種情況,即在i等於0時,也就是說s為空,增加j個字元,使得s轉化為t,在j等於0時,也就是說t為空,就是減少 i個字元,使得s轉化為t。

對於第三種情況,顯然為d(A,B)=0。


演算法描述:

1)現在只剩下普通(一般)情況,運用動態規劃求出遞迴方程,將原問題分解為若干個子問題進行求最優解,後得出原問題的最優解,採用“填表的方法”,設計步驟:對每個子問題只求解一次,將其結果儲存在一張表(構造一個行數為n+1 列數為 m+1 的矩陣 , 用來儲存完成某個轉換需要執行的最少操作的次數)中。然後三步a.描述最優解的結構b.遞迴定義最優解的值c.按自底向上的方式計算最優解的值d.由計算出的結構構造一個最優解,利用解決子問題的最優值從而得出原問題的最優值。

2)矩陣設為d[i][j],儲存從S[0:i]變到t[0:j]的編輯距離。這裡S[0:i]變到t[0:j]有三種情況,要求出這三種情況的最小值作為最小運算元。分別為:

(1)設可以在k1個操作內將s[0:i-1]轉換為t[0:j],用k1+1次操作將s[0:i]轉化為t[0:j],只需要先在“s[0:i]轉化為t[0:j]”的操作開端做1次移除操作移除s[i]將s[0:i]轉化為s[0:i-1],然後再做k1個操作就可以轉換為t[0:j]。對應表格,既矩陣所求d[i][j]的左格。

(2)設可以在k2個操作內將s[0:i]轉換為t[0:j-1],用k2+1次操作將s[0:i]轉化為t[0:j],先用k2次操作將s[0:i]轉化為t[0:j-1],然後再執行1次插入操作在“s[0:i]變成t[0:j-1]的操作”的末尾插入“增加t[j]”的一次操作,即可將s[0:i]轉化為t[0:j]。對應表格,既矩陣所求

d[i][j]的上格。

(3)設可以在k3個操作內將s[0:i-1]轉化為t[0:j-1] s[i]==t[j],S[0:i]變到t[0:j]就只要k3個操作,若s[i]!=t[j],則需1次換操作加在s[0:i-1]轉化為t[0:j-1]的運算元基礎上就可以將S[0:i]變到t[0:j],共k3+1次。對應所求d[i][j]的左上格。

即:(註釋)

     子問題識別符號的含義:從S[0:i]變到t[0:j]的編輯距離。(1<=i<=m,1<=j<=n)

     子問題遞迴公式:

      n   (m == 0 ) ;(n為字串t的長度,m為字串s的長度)

    m    (n== 0 )  ;

     d[j][i] =Math.min(d[j-1][i-1]+1,Math.min(d[j][i-1] + 1,d[j-1][i] + 1 ))   (s.charAt(i-1)!=t.charAt(j-1))  1<=i<=m,1<=j<=n//java編寫

     d[j][i] =Math.min(d[j-1][i-1],Math.min(d[j][i-1] + 1,d[j-1][i] + 1 ))   (s.charAt(i-1)==t.charAt(j-1))  1<=i<=m,1<=j<=n

     原問題最優解:  雙重迴圈掃描完從S[0:i]變到t[0:j]後,即S[0:m]變到t[0:n],最優值為d[n][m]的編輯距離。

3)對於d[i][j]二維陣列,可以開闢為d[n+1][m+1],n為字串t的長度,m為字串s的長度。首先進行如下初始化:

 

再根據以上所說的三種方法來填表,完成後如圖:

 

如圖,最優值為d[n][m]即為所求兩串的編輯距離。

申請二維陣列空間程式碼:

初始化程式碼:

 

掃描陣列的程式碼(即解決每個子問題最終求得原問題解的過程的程式碼):

結合上述所有情況:完整程式碼如下:


**注://之前把當兩個字元相同時直接定為d[j-1][i-1],這個需不需要比較的問題,仍在討論中,保險起見,暫時更改為上述做法。


演算法時間及空間複雜度分析(此次為java編寫):

   由上述程式碼得,求子問題時的雙重迴圈加兩個初始化單迴圈的線性時間,再加上比較等操作的常數時間,得時間複雜度為O(M*N),而空間複雜度,花銷了一個二維陣列的輔助空間,得空間複雜度也為O(M*N)。

對於動態規劃的問題,解決問題前得思考好各種可能出現的情況,並且寫好三步:

      子問題識別符號的含義:

      子問題遞迴公式:

      原問題最優解:

填表方法十分巧妙和便捷,得記牢此方法。