1. 程式人生 > >演算法設計與分析學習筆記——最長公共子序列

演算法設計與分析學習筆記——最長公共子序列



最長公共子問題

待解決問題:

    給定兩個序列X和Y,求其一個最長公共的序列Z。

    補充解釋:X(m)={x1, x2,,,,,xm},Y(n)={y1, y2,,,,,yn},X和Y可以有共同的元素,Z是這些共同元素的集合,其元素順序在XYZ中都是升序排序的(Z中元素的順序不能在X,Y中出現前後顛倒的情況)。

    例子:X={A,B,C,B, D,A, B},Y={B, D,C, A,B,A},那麼序列{B, C, B, A}是X和Y的最長公共子序列。{B, C, A}也是X和Y的子序列,但它不是最長的。

窮舉法

        最常見的方法就是窮舉法,它的思路是:分別列舉出X和Y的所有序列,接著比較X和Y的所有子序列,選擇公共序列,最後選擇長度最長的公共序列,這個公共序列就是我們要求的最長公共子序列。

子結構分析:

        我們發現,如果X和Y的長度都很短(假設長度都為1),我們很容易得出最優解,但是事實往往是很殘酷的。如果給定一組長度很長的X,Y,我們利用分治策略的思路,能不能從X和Y的子段中一步一步得出答案呢?

        分治策略和動態規劃第一步都需要刻畫最優解的結構。下面先來看一下最長公共子序列最優解的結構。

        假設X(m) = {x1, x2.....xm} 和 Y(n) = {y1, y2....yn}的最長公共子序列為Z = {z1, z2....zk},現在考慮一下X(m-1)和Y(n-1)的最優解和Z之間的關係。

            1.如果X和Y的最後一個元素相等,並且等於Z的最後一個元素,那麼說明Z(k-1)是X(m-1)和Y(n-1)的公共子序列

            2.如果xm != yn,並且xm和yn也不等於zk,那麼,Z是X(m-1)和Y(n-1)的公共子序列

            3.如果xm != yn,zk = xm != yn,那麼Z是X(m)Y(n-1)的最長公共子序列

            4.如果xm != yn,zk = yn != xm,那麼Z是X(m-1)Y(n)的最長公共子序列

        在分析了X(m),Y(n)的解的結構之後,再於x(m-1),y(n-1)的解結構作對比,我們可以發現:Z被分類到以上三種情況的哪一種,主要取決於X,Y的最後一個元素是否相等,所以我們可以歸納出一個遞迴函式:

            定義:c[i][j]為X(i)和Y(j)的最長公共序列(i <= m, j <= n)

            判斷退出遞迴條件:如果 i 和 j 有一個等於0,可以立即得出並返回結果:當前兩個子序列的最長公共子序列長度為0。

            比對當前X,Y的最後一個元素。

                如果Xi = Yj,那麼返回結果:c[i][j] = c[i -1 ][j - 1] + 1

                如果Xi != Yj,那麼返回結果:max{ c[i][j - 1], c[i - 1][j] }

        在這個遞迴函式裡,我們每次在求c[i][j]的時候,需要使用c[i-1][j-1]等形式的值,我們一開始是不知道的。例如現在我們要求c[5][4],我在這層函式裡發現需要使用c[4][4]的值,我現在不知道,怎麼辦呢?我們只需要建立一個同樣的函式,並且把(4, 4)這兩個引數送給它就行了,同樣,這個新函式也可能不會直接知道c[4][3]的值,這個新函式可以再建立個同樣的函式,把(4, 3)送進去就行了....直到再建立的函式遇到了退出遞迴的條件,並且向上返回了0這個值。上一層函式拿到這個0值做一次處理之後再向上返回到上一層函式....

動態規劃

        程式碼如下


求解例題c[7][6,]矩陣構造方法及過程

    1.把序列分別按橫向和豎向填入矩陣的第一行和第一列

    2.比對第一行和第一列單元格所對應的兩個字母(黃色區域),字母不同填入前面(或者上面)的數字,字母相同則填入(前面的數字+1),但不得超過這個單元格的行數和列數最小的那一個。

    3.依次按行或按列填入數字。如果單元格對應的字母不同,填入這個單元格正上方和正前方最大的那一個;如果字母相同,填入(這個單元格正上方和正前方最大的數+1),但不得超過行數和列數最小值。

橫向Y,豎向XBDCABA
A000111
B11=MAX(0,1)+01=MAX(0,1)+01=MAX(1,1)+02=MAX(1,1)+12=MAX(1,2)+0
C11=MAX(1,1)+02=MAX(1,1)+12=MAX(1,2)+02=MAX(2,2)+02=MAX(2,2)+0
B11=MAX(1,1)+02=MAX(2,1)+02=MAX(2,2)+03=MAX(2,2)+13=MAX(2,3)+0
D12=MAX(1,1)+12=MAX(2,2)+02=MAX(2,2)+03=MAX(3,2)+03=MAX(3,3)+0
A12=MAX(2,1)+02=MAX(2,2)+03=MAX(2,2)+13=MAX(3,3)+04=MAX(3,3)+1
B12=MAX(2,1)+02=MAX(2,2)+03=MAX(3,2)+04=MAX(3,3)+14=MAX(4,4)+0
最優解還原

      從矩陣右下角開始往左上角尋找+1的記錄,例題矩陣中被塗成了紅色。每尋找到一個+1的單元格,記錄對應的字母並且刪除該單元格右方和下方所有的單元格。此題有兩個解,分別是{B,C,A,B}和{B,C,  B, A}