Tải bản đầy đủ (.pdf) (30 trang)

Bài tập lớn Thiết kế và Phân tích Thuật toán

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (3.45 MB, 30 trang )

Bài tập lớn Thiết kế và Phân tích Thuật toán
Đề số 8: Bài toán tìm xâu con chung dài nhất
Sinh viên : Lê Ngọc Minh
Lớp : Khoa học máy tính
Khoá : 52
SHSV : 20071946
Hà Nội, tháng 11/2010
Mục lục
Chương 1. Giới thiệu 3
Chương 2. Cây hậu tố 4
2.1. Khái niệm 4
2.2. Biểu diễn cây hậu tố trong máy tính 5
2.3. Giải thuật dựng cây hậu tố Ukkonen 6
2.3.1. Cây hậu tố ngầm định (implicit suffix tree) 6
2.3.2. Dựng cây hậu tố ngầm định 7
2.3.3. Liên kết hậu tố (suffix link) 9
2.3.4. Tăng tốc thuật toán sử dụng liên kết hậu tố 9
2.3.5. Thuật toán dựng cây hậu tố ngầm định trong thời gian tuyến tính 12
2.3.6. Dựng cây hậu tố thực sự 13
Chương 3. Cây hậu tố tổng quát 14
3.1. Khái niệm 14
3.2. Biểu diễn cây hậu tố tổng quát trong máy tính 14
3.3. Dựng cây hậu tố tổng quát trong thời gian tuyến tính 15
Chương 4. Bài toán tìm xâu con chung dài nhất 16
4.1. Khái niệm 16
4.2. Tìm xâu con chung dài nhất của hai xâu 16
4.3. Tìm xâu con chung dài nhất của nhiều hơn hai xâu 16
4.3.1. Tính số C(v) 17
Chương 5. Chương trình thử nghiệm 18
5.1. Kết quả thử nghiệm 18
5.2. Hướng dẫn cài đặt chương trình 19


5.3. Hướng dẫn sử dụng chương trình 19
5.3.1. Trực quan hoá cây hậu tố 19
5.3.2. Tìm xâu con chung dài nhất của các xâu lớn 20
5.3.3. Sinh xâu lớn 21
5.4. Hướng dẫn biên dịch mã nguồn 21
5.5. Mã nguồn chương trình 27
Phụ lục A. Tài liệu tham khảo 28
Phụ lục B. Danh mục hình 29
Phụ lục C. Danh mục thuật ngữ 30
Chương 1. Giới thiệu
“Tìm xâu con chung dài nhất bằng cây hậu tố”
Chương 2. Cây hậu tố
2.1. Khái niệm
Định nghĩa: Cây hậu tố T của chuỗi m kí tự S là cây có hướng, có gốc có các tính chất sau:
• Các đường đi từ gốc đến lá tương ứng 1-1 với các hậu tố của S.
• Mỗi nút trong, trừ nút gốc, có ít nhất là hai con.
• Mỗi cạnh được gán nhãn là một xâu con khác rỗng của S.
• Không có hai cạnh nào của cùng một nút có nhãn bắt đầu bằng cùng một kí tự
Ví dụ, chuỗi xabxac có cây hậu tố như Hình 1. Đường đi từ gốc đến nút là 1 tương ứng với toàn bộ
xâu còn đường đi từ gốc đến nút lá 5 cho ta xâu ac, bắt đầu ở vị trí 5 của xâu S.
Định nghĩa của cây hậu tố không đảm báo một cây như vậy luôn tồn tại với mọi xâu S. Nếu một
hậu tố của S lại là tiền tố của một hậu tố khác thì đường đi từ gốc đến nó sẽ không kết thúc bởi một nút
lá. Ví dụ, nếu bỏ chữ c trong xâu S, hậu tố xa là tiền tố của hậu tố xabxa nên không có đường đi nào từ
gốc đến lá tương ứng với xa.
Để đảm bảo luôn dựng được cây hậu tố người ta thường thêm một kí tự đặc biệt vào cuối xâu S,
gọi là kí tự kết thúc, để không có bất cứ hậu tố nào là tiền tố của hậu tố khác. Kí tự này phải không xuất
hiện trong xâu ban đầu, người ta thường chọn một kí tự không có trong bảng chữ cái. Trong các tài liệu
thường kí hiệu là $.
Một số khái niệm liên quan đến cây hậu tố:
• Nhãn của một đường đi bắt đầu từ gốc là xâu nhận được bằng cách ghép các xâu dọc theo

đường đi theo thứ tự.
• Nhãn đường đi của một nút là nhãn của đường đi bắt đầu từ gốc đến nút đó
• Độ sâu chuỗi của một nút là độ dài nhãn đường đi của nút đó
• Độ sâu nút (node-depth) của một nút là số nút trên đường đi từ gốc đến nút đó
• Nhãn của một đường đi kết thúc ở giữa cạnh (u, v) chia nhãn của (u, v) tại một điểm được định
nghĩa là nhãn của u ghép với các kí tự trong nhãn của (u, v) từ đầu đến điểm chia.
Hình 1: Cây hậu tố của chuỗi xabxac
Ví dụ trong Hình 1, nhãn của w là xa, nhãn của u là a và xâu xabx là nhãn của đường đi từ gốc đến
giữa cạnh (w, 1).
2.2. Biểu diễn cây hậu tố trong máy tính
Theo cách đơn giản nhất, mỗi cạnh của cây được gán nhãn đúng bằng một xâu con của S. Do tổng
chiều dài tất cả các xâu con vào cỡ O(m
2
) nên giới hạn dưới cho thời gian tính của thuật toán dựng cây
cũng là O(m
2
).
Để giảm kích thước bộ nhớ và đạt được thời gian tính nhỏ hơn, ta biểu diễn cạnh của cây bằng chỉ
số đầu và chỉ số cuối của nó trong xâu S. Như vậy mỗi cạnh chỉ cần hai số để gán nhãn và số cạnh tối
đa là 2m-1 nên bộ nhớ yêu cầu là O(m).
Hình 2: Cây bên trái là một phần của cây hậu tố cho chuỗi S=abcdefabcuvw với nhãn của cạnh được
viết tường minh. Cây bên phải biểu diễn nhãn sử dụng hai chỉ số. Lưu ý rằng cạnh có nhãn 2,3 cũng có
thể được gán nhãn 8,9
Để cho đơn giản, các hình vẽ và diễn giải sau đây vẫn coi như nhãn của cạnh là cả xâu con của
chuỗi.
2.3. Giải thuật dựng cây hậu tố Ukkonen
Báo cáo này sẽ tiếp cận giải thuật Ukkonen theo cách trước hết trình bày một giải thuật đơn giản,
dễ hiểu nhưng kém hiệu quả sau đó sẽ tăng tốc dần bằng các quan sát bổ sung và các mẹo cài đặt.
2.3.1. Cây hậu tố ngầm định (implicit suffix tree)
Định nghĩa: Cây hậu tố ngầm định của xâu S là cây nhận được từ cây hậu tố của S sau các bước

xử lí:
1. Xoá tất cả các kí tự kết thúc $ trong các nhãn
2. Xoá các cạnh không có nhãn
3. Xoá các nút có ít hơn 2 con
Ví dụ với chuỗi xabxa$ có cây hậu tố như Hình 3, nếu bỏ kí tự kết thúc $, xâu xabxa có một số hậu
tố là tiền tố của hậu tố khác nên chúng ta cần xoá một số cạnh và nút để được cây hậu tố ngầm định
như Hình 4. Xét trường hợp chuỗi xabxac, do kí tự c chỉ xuất hiện duy nhất một lần ở cuối xâu nên cây
hậu tố ngầm định cũng là cây hậu tố.
Giải thuật Ukkonen gồm hai bước:
1. Dựng cây hậu tố ngầm định của xâu S
2. Chuyển cây hậu tố ngầm định thành cây hậu tố thật sự
Hình 3: Cây hậu tố cho chuỗi xabxa$
Hình 4: Cây hậu tố ngầm định cho xâu xabxa
2.3.2. Dựng cây hậu tố ngầm định
Giải thuật chia làm m pha, mỗi bước ta cố gắng thêm một kí tự của xâu S vào cây. Gọi cây tại pha
thứ i là I
i
, đầu tiên ta có cây I
1
với một cạnh duy nhất chứa S
1
. Pha i+1 được chia nhỏ thành i+1 bước
mở rộng trong đó ta thêm kí tự S
i+1
vào hậu tố S[j i] của xâu S[1 i]. Tại bước mở rộng j, xét đường đi
từ gốc có nhãn β=S[j i] và thực hiện một trong ba luật mở rộng sau:
1. N u ế β là nhãn c a m t nútủ ộ lá: kí t Sự
i+1
đ c thêm vào c nh n i v i nút lá đó.ượ ạ ố ớ
2. N u không có đ ng đi nào t ế ườ ừ β b t đ u b ng Sắ ầ ằ

i+1
nh ng có ít nh t m t đ ng đi n i ti p ư ấ ộ ườ ố ế β:
tr ng h p này ta c n thêm m t c nh có nhãn là Sườ ợ ầ ộ ạ
i+1
, nếu β k t thúc gi a m t c nh thì m tế ở ữ ộ ạ ộ
nút m i cũng c n đ c t o.ớ ầ ượ ạ
3. N u ế có đ ng ườ đi n i ti pố ế β b t đ u b ng ắ ầ ằ S
i+1
: không làm gì và chuy n sang b c ti p theo.ế ướ ế
T i b c m r ng i+1 c a pha i+1, ạ ướ ở ộ ủ β là xâu r ng, thu t toán đ n gi n thêm kí t Sỗ ậ ơ ả ự
i+1
bên d i nútướ
g c (tr khi nó đã đó).ố ừ ở
Xét ví d trong ụ Hình 5 và Hình 6, b n h u t đ u tiên k t thúc nút lá nh ng h u t cu i cùng chố ậ ố ầ ế ở ư ậ ố ố ỉ
g m kí t x k t thúc bên trong m t c nh. Khi thêm kí t th sáu b, b n h u t đ u tiên đ c m r ngồ ự ế ộ ạ ự ứ ố ậ ố ầ ượ ở ộ
b ng lu t 1, h u t th năm s d ng lu t 2 và v i h u t th 6 là lu t 3.ằ ậ ậ ố ứ ử ụ ậ ớ ậ ố ứ ậ
Hình 5: Cây hậu tố ngầm định cho xâu axabx trước khi kí tự thứ 6, b, được thêm
Hình 6: Cây hậu tố ngầm định sau khi thêm kí tự b
D th y r ng ta có th tìm đi m k t thúc c a m i h u t trong i+1 h u t c a xâu S[1 i] b ng cáchễ ấ ằ ể ể ế ủ ỗ ậ ố ậ ố ủ ằ
duy t cây t g c v i chi phí th i gian là O(|ệ ừ ố ớ ờ β|). Sau khi đã tìm đ c đi m k t thúc c a h u t , thao tácượ ể ế ủ ậ ố
m r ng ch c n th i gian h ng s .ở ộ ỉ ầ ờ ằ ố
V i cách làm này, s phép toán c b n c n th c hi n là ớ ố ơ ả ầ ự ệ , do đó đ ph cộ ứ
t p tính toán vào kho ng O(nạ ả
3
). Rõ ràng thu t toán này không th c t vì có nh ng cách làm đ n gi nậ ự ế ữ ơ ả
h n đ tìm xâu con chung dài nh t trong th i gian O(nơ ể ấ ờ
2
) trong tr ng h p t i nh t. Chúng ta s xem xétườ ợ ồ ấ ẽ
cách c i ti n gi i thu t trong các ph n sau.ả ế ả ậ ầ
2.3.3. Liên k t h u t (suffix link)ế ậ ố

Định nghĩa: Gọi xα là một xâu bất kì, x là một kí tự và α là một xâu (có thể rỗng). Xét nút trong v
có nhãn là xα, nếu có một nút khác s(v) có nhãn là α, một con trỏ từ v đến s(v) gọi là một liên kết hậu
tố.
Trong Hình 1 (trang 5), nút v có nhãn xa do đó s(v) là nút có nhãn a, tồn tại một liên kết từ v đến
s(v). Trường hợp này α chỉ gồm một kí tự.
Trường hợp đặc biệt khi α là xâu rỗng, liên kết được trỏ đến nút gốc. Nút gốc không được coi là
nút trong và không có liên kết hậu tố nào bắt đầu từ nó.
Bổ đề: Nếu một nút trong mới v có nhãn xα được thêm trong lần mở rộng thứ j của pha i+1 thì
hoặc một đường đi có nhãn α đã tồn tại trong cây hoặc một nút trong mới có nhãn α sẽ được thêm
trong lần mở rộng tiếp theo, j+1 của cùng pha i+1.
CHỨNG MINH: Nút trong mới được tạo ra chỉ khi trường hợp mở rộng thứ hai xảy ra, nghĩa là đường
đi có nhãn xα tiếp nối bởi một kí tự khác kí tự S
i+1
, ta gọi kí tự đó là c. Ở bước mở rộng thứ j+1, ta cố
gắng thêm xâu αS
i+1
vào cây, rõ ràng đường đi có nhãn α đã tồn tại và tiếp nối bởi kí tự c. Có hai
trường hợp xảy ra:
• Nếu đường đi có nhãn α chỉ được tiếp nối bằng kí tự c mà không phải kí tự nào khác hay nói
cách khác chỉ tồn tại đường đi αc mà không tồn tại đường đi αd với mọi d khác c. Luật mở rộng
thứ hai được áp dụng và tạo ra nút s(v) có nhãn α.
• Nếu đường đi có nhãn α còn hai hoặc nhiều hơn kí tự tiếp nối, chẳng hạn αc, αd, chắc chắn
đã tồn tại nút có nhãn α.
Vậy, bổ đề được chứng minh.
Hệ quả: Trong giải thuật Ukkonen, mỗi nút trong mới được tạo ra sẽ có một liên kết hậu tố khi
pha tiếp theo kết thúc.
CHỨNG MINH: Định lí được chứng minh bằng quy nạp.
• Cây đầu tiên, I
1
, thoả mãn định lí vì không chứa nút trong nào.

• Giả sử định lí đúng với cây I
i
, ta cần chứng minh nó vẫn đúng với cây I
i+1
.
• Theo bổ đề trên, nếu một nút trong v được tạo ra trong bước mở rộng j, nút s(v) của nó sẽ được
tạo ra hoặc tìm thấy trong bước mở rộng j+1. Bước mở rộng cuối cùng thêm xâu chỉ gồm kí tự
S
i+1
nên không tạo ra nút trong mới nào.
Vậy, hệ quả được chứng minh. Ta thấy khi xây dựng xong cây I
i+1
, mọi nút trong của nó đều có
liên kết hậu tố, ta có hệ quả tiếp theo.
Hệ quả: Với mọi cây hậu tố ngầm định I
i
, nếu một nút trong có nhãn xα thì có một nút khác của
cây I
i
có nhãn α.
Dựa vào liên kết hậu tố, ta có thể tăng tốc thuật toán để đạt được độ phức tạp tính toán thực tế hơn.
2.3.4. Tăng tốc thuật toán sử dụng liên kết hậu tố
Trong giải thuật đầu tiên, tại pha i+1, bước mở rộng j ta cần tìm đường đi β có nhãn S[j i] mất
thời gian O(|β|). Liên kết hậu tố có thể được sử dụng để giảm độ phức tạp của bước này xuống hằng số.
Đường đi có nhãn S[1 i] chắc chắn phải kết thúc ở lá vì nó là đường đi dài nhất trong cây I
i
. Khi
xây dựng cây I
i
ta lưu lại nút lá tương ứng với toàn bộ xâu đang xét S[1 i]. Bước bổ sung đầu tiên của

pha i+1 lấy nút lá này và áp dụng luật bổ sung thứ nhất do đó chỉ cần thời gian hằng số.
Đặt S[1 i] = xα và (v, 1) là cạnh đến nút lá, nhãn của cạnh là γ, bước mở rộng tiếp theo thuật toán
cần tìm đường đi có nhãn là S[2 i] = α. Nếu v là nút gốc, ta duyệt cây từ gốc theo thuật toán trước.
Nếu v không phải nút gốc thì có một liên kết hậu tố từ v đến nút s(v), ta bắt đầu duyệt cây từ nút s(v).
Đường đi từ vị trí hiện tại có nhãn γ là đường đi từ gốc có nhãn α.
Tại bước mở rộng thứ j với j > 2 ta cũng làm tương tự. Khác biệt duy nhất là nếu xâu S[j-1 i] là
nhãn của một nút trong, khi đó ta theo liên kết hậu tố của nút này. Kể cả khi xâu S[j-1 i] kết thúc ở một
nút lá thì nút cha của nó hoặc là một nút trong (do đó có liên kết hậu tố) hoặc là nút gốc. Vậy ta không
bao giờ phải đi ngược lên quá một cạnh.
Hình 7: Bước mở rộng j>1 trong pha i. Đi lên tối đa là một cạnh từ cuối đường đi S[j-1 i] đến nút v
sau đó theo liên kết hậu tố đến s(v), đi xuống theo đường đi có nhãn
γ
rồi áp dụng luật bổ sung phù
hợp để thêm hậu tố S[j i+1].
Việc tìm đường đi có nhãn γ theo cách thông thường cần thời gian O(|γ|), do đường đi nhãn γ chắc
chắn tồn tại và không có hai cạnh nào cũng xuất phát từ một đỉnh có nhãn bắt đầu bằng cùng một kí tự
nên ta có thể dựa vào kí tự đầu của nhãn và độ dài của cạnh để tìm ra điểm kết thúc của đường đi trong
thời gian tỉ lệ với số nút trên đường đi.
Định lí: Gọi (v, s(v)) là một liên kết hậu tố, độ sâu nút của v tối đa là lớn hơn độ sâu nút của s(v)
một đơn vị.
CHỨNG MINH: Với mỗi nút tổ tiên trong của v có nhãn xβ đều có liên kết hậu tố đến nút có nhãn β.
Tuy nhiên xβ là xâu con của nhãn của v nên β là xâu con của nhãn của s(v) hay nói cách khác tổ tiên
của v có liên kết hậu tố đến một tổ tiên của s(v). Mỗi tổ tiên của v có nhãn đường đi khác nhau (do
nhãn trên các cạnh là xâu khác rỗng) nên các tổ tiên của s(v) được liên kết hậu tố trỏ đến cũng khác
nhau. Ta có một đơn ánh giữa tập các xâu trên đường đi từ gốc đến v (lực lượng của tập này là độ sâu
nút của v) trừ nút gốc và tập các xâu trên đường đi từ gốc đến s(v) (lực lượng của nó là độ sâu nút của
s(v)) do đó v có độ sâu không quá độ sâu của s(v) cộng 1.
Hình 8: Với mỗi nút v trên đường đi x
α
, có một nút s(v) trên đường đi

α
. Tuy nhiên, độ sâu nút của
v có thể lớn hơn, bằng hoặc nhỏ hơn độ sâu nút của s(v) một đơn vị. Ví dụ, nút có nhãn xab có độ
sâu hai, nút có nhãn ab có độ sâu một; nút có nhãn xabcdefg có độ sâu bốn, nút có nhãn abcdefg
có độ sâu năm.
Bổ đề: Mỗi pha của giải thuật Ukkonen có thể được thực hiện trong thời gian O(m).
CHỨNG MINH: Trừ bước mở rộng đầu tiên thực hiện được trong thời gian hằng số, các bước mở
rộng tiếp theo bao gồm việc đi ngược lên từ nút hiện tại không qua một nút, theo liên kết hậu tố đến nút
mới và đi xuống một số nút để tìm ra vị trí kết thúc của đường đi. Ta có thể tính được giới hạn trên của
tổng số thao tác đi xuống bằng nhận xét sau: độ sâu tối đa của cây hậu tố là m. Thật vậy, mỗi cạnh của
cây là một xâu con khác rỗng và đường đi từ gốc đến lá bất kì biểu diễn một hậu tố của cây nên tổng số
cạnh tối đa trên đường đi từ gốc đến một nút lá bất kì bằng m hay độ sâu tối đa của mọi nút là m. Mỗi
pha gồm có i+1 ≤ m b c m r ng, tr b c đ u tiên không c n di chuy n nên s b c đi lên t i đaướ ở ộ ừ ướ ầ ầ ể ố ướ ố
c a m t pha là m. C ng v i m i l n đi theo liên k t h u t đ sâu nút gi m t i đa là m t nên t ng s l nủ ộ ộ ớ ỗ ầ ế ậ ố ộ ả ố ộ ổ ố ầ
gi m đ sâu nút là 2m. Đ sâu c a nút hi n t i không th quá m nên t ng c ng s b c đi xu ng trongả ộ ộ ủ ệ ạ ể ổ ộ ố ướ ố
c pha không quá 3m. V y th i gian tính toán c a m i pha là O(m).ả ậ ờ ủ ỗ
T ng c ng có m pha nên ta có ngay b đ ti p theo:ổ ộ ổ ề ế
B đổ ề: Thu t toán Ukkonen có th đ c th c hi n trong th i gian O(mậ ể ượ ự ệ ờ
2
).
Đ n đây hi u qu c a thu t toán đã đ c c i thi n đáng k tuy nhiên ta v n có th gi m đ ph cế ệ ả ủ ậ ượ ả ệ ể ẫ ể ả ộ ứ
t p tính toán xu ng th i gian h ng s b ng m t vài nh n xét nh .ạ ố ờ ằ ố ằ ộ ậ ỏ
2.3.5. Thu t toán d ng cây h u t ng m đ nh trong th i gian tuy n tínhậ ự ậ ố ầ ị ờ ế
Nh n xét 1ậ : Lu t m r ng s 3 k t thúc m i pha.ậ ở ộ ố ế ỗ
CH NGỨ MINH: N u lu t s 3 đ c áp d ng nghĩa là đ ng đi có nhãn S[j i] ch c ch n đ c n i ti pế ậ ố ượ ụ ườ ắ ắ ượ ố ế
b ng kí t Sằ ự
i+1
nên t t c các đ ng đi có nhãn S[k i] v i k > j cũng v y và lu t th 3 ti p t c đ c ápấ ả ườ ớ ậ ậ ứ ế ụ ượ
d ng cho các b c m r ng còn l i c a pha.ụ ướ ở ộ ạ ủ
G i j* là ch s c a b c m r ng đ u tiên lu t s 3 đ c áp d ng. Theo nh n xét trên ta khôngọ ỉ ố ủ ướ ở ộ ầ ậ ố ượ ụ ậ

c n th c hi n các b c m r ng k v i k > j* trong pha hi n t iầ ự ệ ướ ở ộ ớ ệ ạ .
Nh n xét 2ậ : M t khi đã là nút lá thì luôn luôn là nút lá.ộ
CH NGỨ MINH: Rõ ràng trong 3 luật mở rộng không có luật nào cho phép thêm một nút lá mới bên
dưới một nút lá có nhãn α. Do đó khi một nút lá đã được tạo ra thì nó sẽ luôn luôn là nút lá cho đến khi
pha cuối cùng của thuật toán kết thúc.
Gọi j
i
là bước mở rộng cuối cùng trong pha i mà luật mở rộng 1 hoặc 2 được áp dụng. Xét xâu
S[1 i-1], luật mở rộng 1 áp dụng cho nút lá có nhãn S[1 i-1] mở rộng nó thành S[1 i], luật mở rộng 2
tạo ra một nút lá có nhãn S[1 i] do đó với mọi k ≤ j
i
, nút có nhãn S[1 k] là nút lá. Trong pha i+1 tiếp
theo, các bước mở rộng 1 j
i
đều áp dụng luật 1 nên j
i
≤ j
i+1
.
Nhận xét trên gợi ý cách cài đặt hiệu quả thuật toán: thay vì cập nhật nhãn của các nút lá một cách
tường minh, ta gán nhãn cho các nút lá (lưu ý rằng trong cài đặt nhãn của nút lá là một cặp số nguyên)
là (p, m). Trong đó p là vị trí bắt đầu của xâu con và m là độ dài xâu S, thay thế cho vị trí cuối xâu đang
xét. Như vậy trong pha i+1 ta không cần thực hiện j
i
bước mở rộng tường minh đầu tiên.
Định lí: Sử dụng liên kết hậu tố và các nhận xét trên, giải thuật Ukkonen có thể dựng cây hậu tố
ngầm định trong thời gian O(m).
CHỨNG MINH: Trong mỗi pha i của thuật toán, ta chỉ cần thực hiện các bước mở rộng tường minh từ
j
i-1

đến j
*
. Do bước mở rộng cuối cùng luật 1 hoặc 2 được áp dụng chính là một bước trước khi luật 3
lần đầu tiên được áp dụng nên ta có j
i
= j
*
-1. Như vậy số bước mở rộng được thực hiện có thể tính theo
công thức: . Vậy thời gian thực hiện của thuật toán là
O(m).
Hình 9: Hình ảnh quá trình thực hiện của thuật toán. Mỗi dòng là một giai đoạn trong thuật toán, mỗi
số là một bước mở rộng tường minh được thực hiện.
2.3.6. Dựng cây hậu tố thực sự
Cây hậu tố ngầm định cuối cùng I
m
có thể được chuyển thành cây hậu tố thực sự trong thời gian
O(m). Ta chỉ việc thêm kí tự $ vào cuối xâu S và thực hiện thuật toán, kết quả là một cây hậu tố ngầm
định của một chuỗi mà không có hậu tố nào là tiền tố của hậu tố khác, đồng thời cũng là cây hậu tố
thực sự của xâu.
Tóm lại ta có:
Định lí: Giải thuật Ukkonen dựng cây hậu tố của xâu m kí tự S trong thời gian O(m).
Chương 3. Cây hậu tố tổng quát
3.1. Khái niệm
Trong các phần trên ta đã từng bước xây dựng cây hậu tố cho một chuỗi. Để giải quyết bài toán
xâu con chung lớn nhất của hai hay nhiều chuỗi ta cần mở rộng khái niệm cây hậu tố để chứa nhiều
chuỗi hơn trong một cấu trúc dữ liệu chung.
Định nghĩa: Cho tập các chuỗi {S
1
, S
2

, S
K
}, cây hậu tố tổng quát cho tập các chuỗi nãy là cây
sao cho:
• Các đường đi từ gốc đến lá tương ứng 1-1 với các hậu tố của S
i
.
• Mỗi nút trong, trừ nút gốc, có ít nhất là hai con.
• Mỗi cạnh được gán nhãn là một xâu con khác rỗng của S.
• Không có hai cạnh nào của cùng một nút có nhãn bắt đầu bằng cùng một kí tự.
Để phân biệt hậu tố của các chuỗi khác nhau, mỗi chuỗi được bổ sung một kí tự kết thúc khác
nhau và không có trong bảng chữ cái. Mỗi nút lá của cây tương ứng với một hậu tố của một chuỗi nhất
định và được gán nhãn bằng chỉ số của chuỗi đó. Hình 10 cho ta một ví dụ về cây hậu tố của {xabxa,
abxbx}.
Hình 10: Cây hậu tố cùng với các liên kết hậu tố cho hai chuỗi xabxa và
abxbx
3.2. Biểu diễn cây hậu tố tổng quát trong máy tính
Giống như cây hậu tố, một cạnh hiệu quả để biểu diễn cạnh của cây hậu tố tổng quát là lưu chỉ số
bắt đầu và kết thúc của xâu con thay vì bản thân xâu con đó. Cây hậu tố tổng quát chứa nhiều hơn một
xâu nên cạnh cần lưu cả chỉ số của xâu chứa xâu con nó biểu diễn. Hình ảnh của cây hậu tố tổng quát
cho hai xâu xabxa và abxbx trong bộ nhớ như trong Hình 11.
Hình 11: Cây hậu tố tổng quát cho hai xâu xabxa và abxbx cùng với các liên kết hậu tố trong bộ nhớ
(các chỉ số bắt đầu từ 0)
Nhãn của nút lá là không cần thiết vì xâu chứa nó được xác định qua cạnh duy nhất nối với nó.
3.3. Dựng cây hậu tố tổng quát trong thời gian tuyến tính
Áp dụng giải thuật Ukkonen giới thiệu trong chương trước ta dễ dàng dựng được cây hậu tố tổng
quát trong thời gian O(N) với N là tổng độ dài các xâu.
Đầu tiên ta dựng cây hậu tố thông thường cho xâu S
1
. Với các xâu S

2
, S
3
, S
K
trước tiên ta tìm tiền
tố dài nhất S
k
[1 i] đã tồn tại trong cây. Ta thực hiện các giai đoạn i+1, i+2, m
k
của thuật toán
Ukkonen để mở rộng cây hậu tố tổng quát phủ toàn bộ xâu.
Đi sâu vào chi tiết, việc tìm tiền tố dài nhất đã có trong cây đồng nghĩa với việc tìm đường đi dài
nhất trong cây có nhãn S
k
[1 i] bằng cách quét từng kí tự trên đường đi từ gốc. Có hai trường hợp xảy
ra:
1. Đường đi kết thúc ở nút v (có thể là nút gốc): thêm nút con mới nối với v bằng cạnh có nhãn
là S
k
[i+1].
2. Đường đi kết thúc giữa một cạnh: chia đôi cạnh tại điểm đường đi kết thúc và tạo ra nút mới
v. Tạo nút con của v nối với nó bằng cạnh S
k
[i+1].
Sau khi thực hiện xong bước trên bước mở rộng đầu tiên của giai đoạn i+1 đã hoàn thành, ta có thể
đi theo nút cha của v, theo liên kết hậu tố v.v để thực hiện các bước mở rộng tiếp theo. Lưu ý rằng
trong trường hợp thứ 2 ta cũng cần đảm bảo liên kết hậu tố của v sẽ được thiết lập trong bước mở rộng
tiếp theo.
Chương 4. Bài toán tìm xâu con chung dài nhất

4.1. Khái niệm
Xâu con của một xâu S là xâu thu được bằng cách chọn ra một số kí tự liên tục trong S. Một cách
hình thức, giả sử S = S
1
S
2
S
m
, một xâu Z=S
i+1
S
i+2
S
i+t
là với 0 ≤ i và i+t ≤ m là xâu con của S. Ví dụ,
xâu Z = bcda là xâu con của S = aabcbcdabdab.
Cần phân biệt khái niệm xâu con và dãy con. Dãy con của S là dãy thu được bằng cách xoá bớt đi
một số kí tự trong S hay nói cách khác dãy con là một dãy các kí tự xuất hiện trong S, theo đúng thứ tự
nhưng có thể không liên tục. Ví dụ dcbd là một dãy con của S nhưng không phải xâu con của S.
Cho hai xâu S
1
và S
2
, ta nói Z là xâu con chung của S
1
và S
2
nếu Z đồng thời là xâu con của cả hai
dãy.
Ví dụ, cho S

1
= abcdefg và S
2
= bccdegf ta có:
• Z = bc là xâu con chung.
• Xâu efg không phải xâu con chung.
• Z = bc có độ dài 2 không phải xâu con chung dài nhất vì có
• Xâu cde là xâu con chung có độ dài 3.
• Xâu cde là xâu con chung dài nhất vì không tìm được xâu con chung có độ dài 4.
4.2. Tìm xâu con chung dài nhất của hai xâu
Trong cây hậu tố tổng quát của xâu S
1
và S
2
, đánh dấu các nút trong bằng 1 (hoặc 2) nếu cây con
tại nút đó chứa nút lá có nhãn 1 (hoặc 2). Nhãn của đường đi từ gốc đến mỗi nút được đánh dấu cả hai
là một xâu con chung của hai xâu. Nút có nhãn dài nhất hay độ sâu đường đi lớn nhất cho ta lời giải của
bài toán.
Ví dụ trong Hình 10 (trang 14) các đỉnh u, v, w, t lần lượt tương ứng với các xâu con chung bx,
abx, a, x của hai xâu ban đầu. Xâu con chung dài nhất là abx tương ứng với đỉnh v. Qua hình vẽ ta cũng
nhận thấy rằng khi đã tìm được một đỉnh trong thoả mãn xâu con của nó chứa cả nút lá của S
1
và S
2
thì
không cần xét các đỉnh cha của nó nữa vì đường đi tương ứng với các đỉnh cha chắc chắn ngắn hơn
đường đi của đỉnh đó. Trong trường hợp này việc xét đỉnh w là không cần thiết.
Ta có thể duyệt đồng thời tính độ sâu đường đi cho tất cả các nút trong cây trong thời gian O(|V|+|
E|) bằng giải thuật tìm kiếm theo chiều sâu (DFS). Do số nút và số cạnh của cây đều là O(N) với N là
tổng độ dài hai xâu nên ta có giải thuật tìm xâu con chung dài nhất trong thời gian tuyến tính.

4.3. Tìm xâu con chung dài nhất của nhiều hơn hai xâu
Định nghĩa: Cho K xâu S
1
, S
2
, , S
K
, với mỗi giá trị k từ 2 đến K, gọi l(k) là độ dài của xâu con
chung dài nhất của ít nhất k xâu trong tập đã cho.
Ví dụ, xét tập các xâu {sandollar, sandlot, handler, grand, pantry}, các giá trị l(k) là:
k l(k) xâu con
2 4 sand
3 3 and
4 3 and
5 2 an
Tồn tại thuật giải cho bài toán tìm tất cả các giá trị l(k) cùng với các xâu con tương ứng trong thời
gian tuyến tính O(N) [7]. Thật đáng ngạc nhiên là một lượng lớn thông tin như vậy lại có thể được trích
ra trong thời gian chỉ tỉ lệ thuận với thời gian đọc xâu. Tuy nhiên đây là một giải thuật phức tạp, tài liệu
này chỉ xin trình bày giải thuật có độ phức tạp thời gian O(KN).
Định nghĩa: Với mỗi nút trong v của cây T, gọi C(v) là số chỉ số xâu phân biệt xuất hiện trong các
nút lá của cây con tại nút v.
Khi số C(v) cho mọi nút trong đã biết, ta dễ dàng tính được l(k) với mọi k = 2, 3, , K cùng với vị
trí của các xâu con trong thời gian tuyến tính bằng cách duyệt cây. Trong quá trình duyệt ta xây dựng
mảng V(k) chứa độ sâu đường đi (và xâu con) của nút sâu nhất có C(v) = k. Mảng V sau khi xây dựng
xong chứa xâu dài nhất trong những xâu con xuất hiện đúng k lần trong tập xâu đã cho, do đó V(k) ≤
l(k). Đ tìm l(k) ta duy t m ng V ng c t cu i lên đ u và ghi l i giá tr V(k) l n nh t đã g p hay nóiể ệ ả ượ ừ ố ầ ạ ị ớ ấ ặ
cách khác, n u V(k) là r ng ho c V(k) < V(k+1) thì đ t V(k) = V(k+1). K t qu là m ng l(k) c n tính.ế ỗ ặ ặ ế ả ả ầ
4.3.1. Tính s C(v)ố
Cách đ n gi n nh t đ tính C(v) là ban đ u đ t C(v)=0 cho m i nút trong sau đó th c hi n K l nơ ả ấ ể ầ ặ ọ ự ệ ầ
duy t toàn b cây, trong đó l n th k ta tìm t t c các nút trong v mà cây con t i đó có ch a nút lá cóệ ộ ầ ứ ấ ả ạ ứ

ch s xâu là k và tăng giá tr C(v) lên m t đ n v .ỉ ố ị ộ ơ ị
M i l n duy t c n th i gian O(N) do s nút c a cây tăng tuy n tính v i N nên t ng công K l nỗ ầ ệ ầ ờ ố ủ ế ớ ổ ầ
duy t ta m t kho ng th i gian O(KN), đây cũng là đ ph c t p th i gian c a toàn b thu t toán tìm cácệ ấ ả ờ ộ ứ ạ ờ ủ ộ ậ
xâu con chung dài nh t c a K xâu.ấ ủ
Chương 5. Chương trình thử nghiệm
5.1. Kết quả thử nghiệm
Hình 12 cho thấy thời gian dựng cây hậu tố phụ thuộc tuyến tính vào độ dài xâu.
Hình 13 cho thấy thời gian giải bài toán k-xâu con chung lần lượt với 2, 3, 4, 5 xâu có độ dài bằng
nhau. Đồ thị thể hiện rất rõ sự phụ thuộc tuyến tính của thuật toán vào tích của số xâu và độ dài xâu.
Chương trình thử nghiệm được cài đặt bằng ngôn ngữ C, chạy trên máy Intel Core Duo với 1Gb
bộ nhớ trong.
Hình 12: Đồ thị thời gian dựng cây hậu tố phụ thuộc vào kích thước xâu. Kích thước tính theo đơn vị
4Kb, thời gian tính theo giây.
5.2. Hướng dẫn cài đặt chương trình
Chương trình cs-suffix-tree sử dụng bộ giao diện đa nền GTK+ và phần mềm GraphViz để trực
quan hoá cây hậu tố. Chương trình có thể chạy trên hệ điều hành *nix và Windows.
Một bản GTK được phát hành kèm với chương trình, để chạy chương trình bằng bản này hãy dùng
tệp cs-suffix-tree.bat. Nếu đã cài GTK trong máy và thư mục bin có trong biến môi trường PATH của
Windows, người sử dụng có thể chạy trực tiếp tệp cs-suffix-tree.exe.
Bộ cài đặt GraphViz đi kèm với chương trình và cần được hoàn thành trước khi chạy chương
trình. Sau khi cài đặt xong GraphViz người dùng cũng nên thêm thư mục bin (chẳng hạn “C:\Program
Files\Graphviz2.26.3\bin”) vào biến môi trường PATH của Windows để tiện lợi khi sử dụng.
5.3. Hướng dẫn sử dụng chương trình
5.3.1. Trực quan hoá cây hậu tố
Kích hoạt chương trình bằng cách chạy tệp cs-suffix-tree.bat hoặc cs-suffix-tree.exe không có
tham số.
Màn hình chương trình gồm hai phần:
• Phần thông tin bên tay trái
• Phần hình ảnh bên tay phải
Người sử dụng nhập ít nhất là một xâu vào trong các text box có nhãn S1, S2, , S5 và nhấn nút

Hình 13: Thời gian dải bài toán k-xâu con chung theo độ dài xâu. Các xâu được sinh ngẫu nhiên có độ
dài bằng nhau (tính theo Kb).
“Tính”. Chương trình sẽ tạo ra hình ảnh của cây hậu tố qua các bước xây dựng và tự động hiển thị kết
quả cuối cùng là cây hậu tố tổng quát cho những chuỗi (khác rỗng) đã nhập.
Người sử dụng có thể nhấn các nút “Trước” / “Sau” / “Đầu” / “Cuối” hoặc nhập số thứ tự để hiển
thị các hình ảnh trong chuỗi hình ảnh đã được tạo ra.
Đồng thời các xâu con chung dài nhất của ít nhất là k chuỗi trong các chuỗi đã cho cũng được hiển
thị ở bên dưới các nút dịch chuyển.
Mục “Đường dẫn đến dot” là đường dẫn đến tệp thực thi của chương trình “dot” trong thư viện
GraphViz. Nếu thư mục bin của GraphViz đã nằm trong PATH thì có thể để nguyên là “dot”, nếu
không người sử dụng cần nhập đường dẫn đến tệp dot.exe vào mục này.
5.3.2. Tìm xâu con chung dài nhất của các xâu lớn
Chạy tệp cs-suffix-tree.bat hoặc cs-suffix-tree.exe với cú pháp:
cs-suffix-tree -c file1 file2 [file3 [file4 […] ] ]
Trong đó:
• -c (compare) là mã chức năng.
• filen là đường dẫn đến các file cần so sánh, tối thiểu phải có hai file.
Chương trình sẽ so sánh k xâu được cung cấp (nội dung của mỗi tệp là một xâu) và trả về xâu con
chung dài nhất của ít nhất 2, 3, 4, , k xâu trong đó. Kết quả được in ra màn hình, nếu muốn người sử
dụng có thể dùng cú pháp “> outfile” để lưu ra tệp.
Giới hạn: kích thước mỗi tệp không quá 1MB, số tệp không quá 20.
5.3.3. Sinh xâu lớn
Chạy tệp cs-suffix-tree.bat hoặc cs-suffix-tree.exe với cú pháp:
cs-suffix-tree -g fileSize fileCount filePattern
Trong đó:
• fileSize là kích thước tệp tính theo byte.
• fileCount là số tệp cần sinh
• filePattern là mẫu tên file theo định dạng của hàm printf trong C, trong đó phải chứa %d
Chương trình chọn ngẫu nhiên một danh sách từ có sẵn (tiếng Việt) để tạo xâu. Độ dài xâu không
cố định mà chọn ngẫu nhiên trong khoảng fileSize/2 đến fileSize.

5.4. Hướng dẫn biên dịch mã nguồn
Để biên dịch mã nguồn trên Linux chỉ cần cài Eclipse với plugin CDT.
Để biên dịch mã nguồn trên Windows ngoài Eclipse + CDT còn cần thiết lập môi trường lập trình
gồm có (các tệp cài đặt được đặt trong thư mục dev của gói sản phẩm):
• MinGW ( hoặc mingw-get-inst-20101030.exe): tạo môi trường biên
dịch GNU C trên hệ điều hành Windows.
• MSYS ( đi kèm với bộ cài MinGW): một số công cụ cần
thiết để biên dịch chương trình GNU C.
• GTK ( hoặc gtk+-bundle_2.22.0-
20101016_win32.zip): thư viện giao diện, giải nén vào thư mục C:\GTK.
Giao diện chương trình được thiết kế bằng chương trình Glade và chứa trong tệp ui.glade. Để xem
tệp này cần cài đặt Glade 3 ( hoặc tệp
glade3-3.6.7-with-GTK+.exe trong thư mục dev).
Sau khi cài đặt các gói phần mềm trên, cần thiết lập môi trường để Eclipse có thể tìm được các tệp
thực thi cũng như các tệp header của thư viện. Tốt nhất là nên thêm đường dẫn đến thư mục bin của
MinGW, bin của MSYS (nằm trong MinGW), bin của GTK vào biến môi trường PATH của Windows.
Một số hình ảnh về cách cấu hình dự án trong Eclipse như sau (phải chuột vào tên dự án, chọn
Properties ):
Hình 14: Cấu hình Linker: thêm cờ mms-bitfields
Hình 15: Cấu hình assembler: thêm cờ mms-bitfields
Hình 16: Cấu hình compiler: thêm cờ mms-bitfields

×