Dãy con chung dài nhất.

Một phần của tài liệu Thuật toán và một số thuật toán sơ cấp (Trang 46 - 50)

2. QUY HOẠCH ĐỘNG 1 Mở đầu

2.6. Dãy con chung dài nhất.

Một lĩnh vực quan trọng của thiết kế thuật tốn là nghiên cứu các chuỗi ký tự. Một trong số các bài tốn quan trọng nhất trong lĩnh vực này là tìm kiếm một cách hiệu quả một chuỗi (hay nĩi chung là một mẫu nào đĩ) trong một văn bản lớn. Trong nhiều tình huống ta lại chỉ cần tìm sự xuất hiện trong văn bản của những chuỗi “tương tự” với một chuỗi nào đĩ. Chẳng hạn trong lĩnh vực nghiên cứu di truyền. Các mã di truyền được lưu như những phân tử DNA dài. Các chuỗi DNA cĩ thể ngắt thành một dãy dài, mỗi dãy gồm một trong bốn loại cơ bản: C, G, T, A. Nhưng sự so khớp chính xác ít khi xảy ra trong sinh học vì những thay đổi nhỏ trong bản sao DNA. Vì vậy người ta quan tâm tới việc xác định mức độ giống nhau giữa các chuỗi khơng hồn tồn như nhau. Một trong các phương pháp đo mức độ giống nhau giữa hai chuỗi là tính dãy con chung dài nhất.

Bài tốn: Xét chuỗi ký tự như một dãy ký tự.

Cho trước hai dãy X=(x1, x ,.., x2 m) và Z=(z , z ,.., z1 2 k) , ta nĩi Z là dãy con của X nếu cĩ một dãy tăng thực sự của k chỉ số (i1, i ,.., i2 k) (1 i < i <...< i m) sao cho 1 2 k

Z = (xi1, xi , .., xi 2 k).

Chẳng hạn giả sử X=(ABRACADABRA) và Z=(AADAA) thì Z là dãy con của X. Cho trước hai chuỗi X và Y, dãy con chung dài nhất của X và Y là dãy dài nhất Z vừa là dãy con của X vừa là dãy con của Y. Lưu ý rằng dãy con chung dài nhất khơng phải lúc nào cũng duy nhất. Chẳng hạn dãy con chung dài nhất của (ABC) và (BAC) hoặc là (AC) hoặc là (BC).

Bài tốn đặt ra là tìm một dãy con chung dài nhất của hai dãy cho trước.

Một cách giải đơn giản là thử tất cả các dãy con cĩ thể của một dãy và tìm kiếm sự xuất hiện của chúng trong dãy thứ hai. Thuật tốn này rất khơng hiệu quả vì số dãy con cần thử rất lớn. (Nếu dãy X cĩ độ dài n, dãy Y cĩ độ dài m, thì số dãy con cần thử là bao nhiêu?).

Theo cách tiếp cận quy hoạch động ta sẽ ngắt bài tốn đã cho thành những bài tốn nhỏ hơn. Ta sẽ xem xét một trong những cách làm như vậy.

Một tiền tố của một dãy là một dãy con các phần tử liên tiếp kể từ đầu dãy. Như vậy các tiền tố của X = (x1, x ,.., x2 m) sẽ là Xi = (x , x ,.., x1 2 i) với 0  i  m trong đĩ X là dãy 0 rỗng và X = X. Ta sẽ đi tìm dãy con chung dài nhất ứng với mỗi cặp tiền tố cĩ thể của X m và Y.

Gọi c[i,j] là độ dài dãy con chung dài nhất của Xi và Yj, ta sẽ đi tính c[m,n]. Để tính c[i,j] dựa vào các giá trị c[h,t] với h  i và t j ta xét các trường hợp sau:

 x = yi j. Ví dụ Xi = (ABCA) và Yj = (DACA), vì cả hai kết thúc là A nên ta khẳng định dãy con chung dài nhất của chúng cũng kết thúc là A. Do đĩ trong trường hợp này ta cĩ thể kết luận c[i,j] = c[i-1,j-1] + 1.

 xi  y . Khi x và yj đĩ i j khơng thể đồng thời cĩ trong dãy con chung dài nhất vì nếu vậy chúng đều nằm cuối dãy con chung dài nhất. Nếu x khơng nằm trong dãy con chung dài i

nhất thì dãy con chung dài nhất của X và Yj sẽ là dãy con chung dài nhất của Xi i-1 và Y , khi j đĩ ta cĩ c[i,j] = c[i-1,j]. Nếu yj khơng nằm trong dãy con chung dài nhất thì dãy con chung dài nhất của Xi và Yj sẽ là dãy con chung dài nhất của Xi và Y , khi j-1 đĩ ta cĩ c[i,j] = c[i,j-1]. Như vậy nếu xi y thì c[i,j] = max(c[i-1,j], c[i,j-1]). j

Trường hợp cơ sở: c[i,0] = c[0,j] = 0. Mơ tả thuật tốn như sau:

int LCS(char X[],char Y[], int n,int m, );

Khởi tạo c[i,0] = c[0,j] = 0 với mọi i, j: 0  i  m, 0 j  n. For (i=1;i<=m;i++) {

For (j=1;j<=n;j++) {

If (X[i]==Y[j]) {c [i,j]= c[i-1,j-1]+1 ;}

Else {

If (c[i-1,j] >= c[i,j- ) c[i,j] = c[i-1,j]; } 1] { Else c[i,j] = c[i,j-1]; } {

}

}

}

Return c[m,n];

Bài tập: a/ Hãy xác định các giá trị ban đầu và cách truy vết để chỉ ra một dãy con

chung dài nhất trong trường hợp tìm được.

b/ Cĩ thể cải biên thuật tốn chỉ dùng mảng 1 chiều hay khơng?

Gợi ý: Cĩ một phương pháp cài t tđặ ốt hơn, ựa d trên nh xét sau: ận để tính ơ c[ j], i, ta chỉ cần 3 ơ c[i 1,j 1] c– – , [i–1,j] c[i,j 1]. T– ức là để tính dịng c[i] thì chỉ cần

dịng c[i–1]. Do đĩ tachỉ ần c 2 mảng 1 chiều để ưu l dịng vừa tính và dịng đang tính.

2.7. Nhận xét

Rất nhiều bài tốn tối ưu yêu cầu đi tìm một cấu hình tối ưu. Khi áp dụng kỹ thuật quy hoạch động để giải quyết những bài tốn như vậy ta thường tiến hành theo 2 bước:

- Bước thứ hai: Dựa vào bảng đã lập ở bước thứ nhất để xác định một cấu hình tối ưu tương ứng. Đơi khi phải bổ sung thêm một bảng khác để làm căn cứ truy tìm một cấu hình tương ứng.

2.8. BÀI TẬP

Một phần của tài liệu Thuật toán và một số thuật toán sơ cấp (Trang 46 - 50)

Tải bản đầy đủ (PDF)

(71 trang)