Ta gọi dãy con của một dãy cho trước là dãy thu được từ dãy đã cho bằng việc loại bỏ một số phần tử. Một cách hình thức, giả sử cho dãy X = <x1, x2, …, xm>, dãy Z = <z1, z2, …, zk> được gọi là dãy con của dãy X nếu tìm được dãy các chỉ số 1? i1 < i2 < … < ik ? n sao cho zi = xi j, j = 1, 2, …, k. Chẳng hạn dãy Z = < B, C, D, B> là dãy con của dãy X = <A, A, B, C, B, C, D, A, B, D, A, B> với dãy chỉ số là <3, 4, 7, 9>.
Cho hai dãy X và Y ta nói dãy Z là dãy con chung của hai dãy X và Y nếu Z là dãy con của cả hai dãy này. Ví dụ, nếu X = <A, B, C, D, E, F, G> và Y = <C, C, E, D, E, G, F> thì dãy Z = <C, D, F> là dãy con chung của hai dãy X và Y, còn dãy <B, F, G> không là dãy con chung của chúng. Dãy <C, D, F> không là dãy con chung dài nhất vì nó có độ dài 3 (số phần tử trong dãy), trong khi đó dãy <C, D, E, G> là dãy con chung của X và Y có độ dài 4. Dãy <C, D, E, G> là dãy con chung dài nhất vì không tìm được dãy con chung có độ dài 5.
Bài toán dãy con chung dài nhất được phát biểu như sau: Cho hai dãy X = <x1,x2,…,xm> và Y = <y1,y2,…,yn>. Cần tìm dãy con chung dài nhất của hai dãy X và Y.
Thuật toán trực tiếp để giải bài toán đặt ra là: Duyệt tất cả các dãy con của dãy X và kiểm tra xem mỗi dãy như vậy có là dãy con của dãy Y, và giữ lại dãy con dài nhất. Mỗi dãy con của X tương ứng với dãy chỉ số <i1,i2, …, ik> là tập con k phần tử của tập chỉ số {1, 2, …, m}, vì thế có tất cả 2m dãy con của X.Như vậy thuật toán trực tiếp đòi hỏi thời gian hàm mũ và không thể ứng dụng được trên thực tế. Ta xét áp dụng quy hoạch động để xây dựng thuật toán giải bài toán này.
Phân rã . Với mỗi 0 ? i ? m và 0 ? j ? n xét bài toán C(i,j); tính C[i,j] là độ dài của dãy con chung dài nhất của hai dãy.
Xi=<x1,x2,…,xi>
và
yi=<y1,y2,…yi>
Như vậy ta đã phân bài toán cần giải ra thành (m+1)x(n+1) bài toán con. Bản thân bài toán xuất phát là bài toán con có kích thước lớn nhất C(m,n).
Tổng hợp lời giải. Rõ ràng
c[o,j]=0,j =0,1,…,n và c[i,0]=0,i=0,1,…,m.
Giả sử i>0,j>0 ta cần tính c[i,j] là độ dài của dãy con chung lớn nhất của hai dãy Xi và Yi có hai tình huống:
Nếu Xi =Yi thì dãy con chung dài nhất của Xi vàYi sẽ thu được bằng việc bổ sung Xi vào dãy con chung dài nhất của hai dãy Xi-1và Yj-1
Nếu Xi Yi thì dãy con chung dài nhất của Xi và Yj sẽ là dãy con dài nhất trong hai dãy con chung dài nhất của (Xi và Yi) và của (Xi-1 và Yj) . Từ đó ta có công thức sau để tính C[i,j].
nÕu i=0 hoÆc j=0nÕu i,j >0 vµ xi=yjnÕu i,j >0 vµ xi yj
ThuËt to¸n t×m d·y con chung dµi nhÊt cã thÓ m« t¶ nh sau.
Procedure LCS(X,Y);
begin
for i :=1 to m do c[i,0]:=0;
forj: =1 to n do c[0,j:=0;
for i: =1 to m do
for j: = 1to n do
if xi = yi then
begin
c[i,j]:=c[i-1,j-1]+1;
b[i,j]:=/;
end
else
if c [i-1,j] ≥ c[i,j-1] then
begin
c[i,j]:=c[i-1,j];
b[i,j]:= ;
end
else
begin
c[i,j]:=c[i,j-1];
b[i,j]:= ;
end;
end;
Trong thủ tục mô tả ở trên ta sử dụng biến b[i,j] để ghi nhận tình huống tối ưu khi tính giá trị c[i,j]. Sử dụng biến này ta có thể đưa ra dãy con chung dài nhất của hai dãy X và Y nhờ thủ tục sau đây:
Procedure Print LCS (b,X,i,j);
begin
if(i=0)or (j=0) then return;
if b[i,j]=/ then
begin
print LCS (b,X,i-1,j-1);
print xi; (* §a ra ph©n tö xi *)
end
else
if b[i,j]= then
PrintLCS (b,X,i-1,j)
else
Print LCS (b,X,i,j-1);
end;
Dễ dàng đánh giá được thời gian tính của thuật toán LCS là 0(mn).
- Thiết kế và đánh giá thuật toán
- Lời nói đầu
- Bài 1: Thuật toán và độ phức tạp
- Bài 2:Phân tích thuật toán
- Bài 3: Cơ bản về thuật toán chia để trị
- Bài 4: Các bài toán sử dụng thuật toán chia để trị ( Divid and Conquer )
- Bài 5: Cơ bản về thuật toán Quay Lui (Back Tracking)
- Bài 6: Cơ bản về thuật toán nhánh cận và các bài toán
- Bài 7: Cơ bản về thuật toán Tham Lam
- Bài 8: Cơ bản về thuật toán Quy hoạch động
- Bài 9: Các bài toán sử dụng thuật toán Quy hoạch động
- Bài 10: Bài tập và tổng kết
- Tài liệu tham khảo