前言
動態(tài)規(guī)劃
動態(tài)規(guī)劃
動態(tài)規(guī)劃其實就是對分而治之策略的一種應用, 將一個較大的問題分解成有限個的不相關(guān)的子問題問題, 然后通過解決子問題, 不斷推演出最終結(jié)果。
動態(tài)規(guī)劃有一個比較直觀特點: 就可以通過表格的方式去描述問題。
動態(tài)規(guī)劃應用
以下使用動態(tài)規(guī)劃進行字符串最短編輯處理的一個例子,通過這個例子就可以很容易的搞懂動態(tài)規(guī)劃這個算法的原理和應用。
1、字符的操作方式
字符的三種操作方式: 替換, 刪除, 增加。
舉個例子:
替換
abc -> abe
里面就需要將c 提換成e, 這里需要的操作次數(shù)是1。
刪除
abc -> ab
里面就需要將c 刪除, 這里需要的操作次數(shù)是1.
增加
a -> ab
里面就需要增加字符b, 這里需要的操作次數(shù)是1.
從上面的例子可以看到, 其實兩個字符串即便互相交換, 它們的最短操作距離是一樣的。
2、使用動態(tài)規(guī)劃解決最短編輯距離問題
. 將 adceg --> abcfg
步驟一: 初始化表格
. 首先, 我們根據(jù)比較字符串的長度新建一個 (m+1)x(n+1) 的二維表格, 這個例子中, 這個表格就是6x6, 當然, 需要比較字符串的長度不需要相等.,
. 然后, 初始化首行與首列的數(shù)據(jù)
其實,初始化的原理是和之前說的編輯邏輯保持一致的, 我們先看第一行:
.Null 表示空串, 第0,0 坐標的值是0, 表示, "空串" --> "空串" 無需任何編輯操作
.0,1 坐標的值是1, 表示從"空串" --> "a", 只需要最少1次編輯操作.
.0,2 坐標的值是2, 表示從"空串" --> "ab", 只需要最少2次編輯操作.
同理可得, 第一行剩下的值分別是3,4,5
.同樣地, 我們也可以得到第一列的值分別是 0,1,2,3,4,5
步驟二: 解決字符相等的情況
.完成了初始化后, 我們嘗試填充 1, 1 坐標的值
.由于第一行的字母是a, 第一列的字母也是a, 兩者相等,所以我們只需要將(i-1, j-1)也就是(0,0) 的值直接復制過來, 也就是說, (1,1) 的值是0, 表示無需任何編輯操作.如下圖所示
步驟三: 解決字符不相等的情況:
.好了, 我們繼續(xù)填充(1,2) 坐標的值:
.i 對應的值依舊是a, j 對應的值b, 但兩者不相等,這個時候, 需要我們就取 replace, insert, remove 操作對應的坐標值中的最小值. 這么說可能比較抽象, 我們先從微觀上觀察下每一個種操作對應的坐標值:
假設當前的坐標是i,j (i>0, j >0). 那么:
insert 操作對應的坐標值是(i, j-1)
replace 操作對應的坐標值是 (i-1, j -1)
remove 操作對應的坐標值是 (i-1, j)
我們需要做的,就是將這三種操作的最小值找出來, 然后做 +1 操作, 以 (1,2) 為例,填的值就是1:
步驟四: 填充剩余表格
.好了, 到目前為止, 所有的需要分析的步驟就完成了, 剩下就只需要填充后面的值,最后,你會發(fā)現(xiàn)2 就是最終的求解.
.動態(tài)規(guī)劃一個很大的優(yōu)勢就是可以通過這個表格找出任意兩個子串的最短編輯距離, 比如: abc --> adc 的最短編輯距離就是1
算法實現(xiàn):
最終的算法實現(xiàn)(Python)就非常簡單了:
def min_dest(i, j, arr): return min(arr[i-1,j-1], min( arr[i-1,j], arr[i,j-1])) def find_min_edit_distance(str1, str2): arr = [len(str1)][len(str2)] for i in range(len(str1)): for j in range(len(str2)): if i == 0: #初始化第0行 a[i][j] = j continue if j == 0: #初始化第0列 a[i][j] = i continue if str1[i] == str2[j]: #字符相等, 直接復制 a[i][j] = a[i-1][j-1] else: #字符不等, 去最小值. a[i][j] = min_dest(i, j, arr) return arr[len(str1)-1][len(str2)-1]
總結(jié):
從這個例子可以看到: 動態(tài)規(guī)劃的實現(xiàn)一點都不難, 難是難在要識別問題能通過動態(tài)規(guī)劃去解決. 我認為這個過程是需要不斷積累經(jīng)驗的過程.