《演算法導論》實驗二 最長公共子串行(LCS)演算法

2021-07-08 20:30:33 字數 3278 閱讀 8907

子串行定義:x=(x1,x2,····,xm),序列z=(z1,z2,····,zk)是x的一子串行,必須滿足:若x的索引中存在乙個嚴格增的序列i1,i2,····,ik,使得對所有的j=1~k,均有xij=zj。

兩個序列的公共子串行:z是x和y的子串行,則z是兩者的公共子串行cs。

最長公共子串行(lcs):在x和y的cs中,長度最大者為乙個最長公共子串行lcs。

cpu:奔騰 t4300

記憶體:4g

作業系統:windows7 ;

軟體平台:vs2010

1、演算法思想:因為lcs問題滿足最優子結構和重疊子區間,所以可用動態規劃的方法來設計演算法。

2、lcs的最優子結構性質:

設序列x=(x1, x2, …, xm)和y=(y1, y2, …, yn)的乙個最長公共子串行z=(z1, z2, …, zk),則:

(1)若xm=yn,則zk=xm=yn且zk-1是xm-1和yn-1的最長公共子串行;

(2)若xm≠yn且zk≠xm ,則z是xm-1和y的最長公共子串行;

(3)若xm≠yn且zk≠yn ,則z是x和yn-1的最長公共子串行。

其中xm-1=(x1, x2, …, xm-1),yn-1=(y1, y2, …, yn-1),zk-1=(z1, z2, …, zk-1)。

兩個序列的最長公共子串行包含了這兩個序列的字首的最長公共子串行。因此,最長公共子串行問題具有最優子結構性質。

3、子問題的遞迴結構:

由最長公共子串行問題的最優子結構性質可知,要找出x=(x1, x2, …, xm)和y=(y1, y2, …, yn)的最長公共子串行,可按以下方式遞迴地進行:當xm=yn時,找出xm-1和yn-1的最長公共子串行,然後在其尾部加上xm(=yn)即可得x和y的乙個最長公共子串行。當xm≠yn時,必須解兩個子問題,即找出xm-1和y的乙個最長公共子串行及x和yn-1的乙個最長公共子串行。這兩個公共子串行中較長者即為x和y的乙個最長公共子串行。

由此遞迴結構容易看到最長公共子串行問題具有子問題重疊性質。例如,在計算x和y的最長公共子串行時,可能要計算出x和yn-1及xm-1和y的最長公共子串行。而這兩個子問題都包含乙個公共子問題,即計算xm-1和yn-1的最長公共子串行。

與矩陣連乘積最優計算次序問題類似,我們來建立子問題的最優值的遞迴關係。用c[i,j]記錄序列xi和yj的最長公共子串行的長度。其中xi=(x1, x2, …, xi),yj=(y1, y2, …, yj)。當i=0或j=0時,空序列是xi和yj的最長公共子串行,故c[i,j]=0。

4、計算最優值:

計算最長公共子串行長度的動態規劃演算法lcs_length(x,y)以序列x=(x1, x2, …, xm)和y=(y1, y2, …, yn)作為輸入。輸出兩個陣列c[0..m ,0..n]和b[1..m ,1..n]。其中c[i,j]儲存xi與yj的最長公共子串行的長度,b[i,j]記錄指示c[i,j]的值是由哪乙個子問題的解達到的,這在構造最長公共子串行時要用到。最後,x和y的最長公共子串行的長度記錄於c[m,n]中。

5、構造最長公共子串行

由演算法lcs_length計算得到的陣列b可用於快速構造序列x=(x1, x2, …, xm)和y=(y1, y2, …, yn)的最長公共子串行。首先從b[m,n]開始,沿著其中的箭頭所指的方向在陣列b中搜尋。當b[i,j]中遇到」↖」時,表示xi與yj的最長公共子串行是由xi-1與yj-1的最長公共子串行在尾部加上xi得到的子串行;當b[i,j]中遇到」↑」時,表示xi與yj的最長公共子串行和xi-1與yj的最長公共子串行相同;當b[i,j]中遇到」←」時,表示xi與yj的最長公共子串行和xi與yj-1的最長公共子串行相同。

圖-1 計算最優解值,即計算二維陣列c和b

圖-2 遞迴法構造乙個lcs

本實驗的測試用例是測試兩個dna序列的最長公共子串行。實驗結果截圖如下圖-3:

圖-3 實驗結果截圖

1、 總體而言,優化後的快速排序比普通快速排序更優,時間開銷更小(除了極個別離群點外,因為離群點可能因為實驗裝置突發工作狀態有關)。

2、 時間開銷隨k值的變化的規律不是很明顯,趨勢不單一,更像是週期分布。

3、 當問題規模比較大且k值也很大時,優化的快排時間開銷反而比普通快排大。實驗者個人認為,其原因在於此時從巨集觀的角度看,插入排序佔據的比例較大,因此時間開銷也較大。

4、不同的問題規模的最佳k值不同,但k的最佳取值隨問題規模的增大而變小,此規律較難解釋,需要後期話時間研究研究。

#include 

using

namespace

std;

#define maxsize 50

//計算最優解值,即計算二維陣列c和b 時間複雜度o(mn)

void lcs_length(char *x,char *y,int c[maxsize],int b[maxsize])

else

if(c[i-1][j]>c[i][j-1]) //c[i][j]取max

else

}}//遞迴法構造乙個lcs

void print_lcs(int b[maxsize],char *x,int i,int j)

else

if(b[i][j]==1)

print_lcs(b,x,i-1,j);

else

print_lcs(b,x,i,j-1);

}int main()

; //宣告二維輔助陣列c和b,並初始化元素全為0

int b[maxsize][maxsize]=; //數字0表示「↖」,數字1表示"↑" ,數字-1表示"←"

cout

<

<

lcs_length(x,y,c,b);

print_lcs(b,x,strlen(x),strlen(y));

cout

}

演算法導論 最長公共子串行

華電北風吹 日期 2016 2 24 問題描述 給定兩個序列x x1,x2,x m 和y y1,y 2,yn 求 x 和 y的長度最長的公共子串行。子串行 給定乙個序列x x1,x2,x m 若另乙個序列z z1,z2,z k 滿足存在乙個嚴格遞增的下標序列i1 i2,ik使得對所有的j 1,2,k...

演算法導論 最長公共子串行

一 演算法設計與分析 設計lcs length演算法,概算福接受兩個序列x 1.m y 1.n 為輸入。它將c i,j 的值儲存在表c 0 m,0 n 並按照行主序計算表項。過程維護乙個表b 1 m,1 n 幫助構造最優解。b i,j 指向的表項對應計算c i,j 時所選擇的子問題最優解。偽 如下 ...

演算法 最長公共子串行

好久沒做演算法題了,現在發現自己的演算法能力非常薄弱,所以特意練練,順便做個筆記方便以後檢視。今天整理一下最長公共子串行,最長公共子串行的問題常用於解決字串的相似度,是乙個非常實用的演算法,作為碼農,此演算法是我們的必備基本功。最長公共子串行,是指兩個字串可具有的長度最大的公共的子串行。聽著好像有點...