Cây hậu tố, mảng hậu tố, và ứng dụng

15 615 5
Cây hậu tố, mảng hậu tố, và ứng dụng

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Mảng hậu tố là một cấu trúc dữ liệu trong việc xử lý các bài toán về xâu. Nó hỗ trợ các thuật toán tìm kiếm xâu, thành lập từ điển, tìm xâu con chung một cách nhanh chóng và hiệu quả. Trong khuôn khổ thời gian của một cuộc thi lập trình, việc biết rõ về mảng hậu tố để giải quyết những bài toán là rất cần thiết, đặc biệt là tại kỳ thi ACMICPC, IOI, ...

SỞ GIÁO DỤC VÀ ĐÀO TẠO THÀNH PHỐ CẦN THƠ TRƯỜNG THPT CHUYÊN LÝ TỰ TRỌNG TỔ TIN HỌC CHUYÊN ĐỀ CÂY HẬU TỐ, MẢNG HẬU TỐ VÀ ỨNG DỤNG Học sinh thực hiện: Hoàng Văn Thiên Lớp: 11A2-P Năm học: 2015 – 2016 2|Trang MỤC LỤC I ĐẶT VẤN ĐỀ II NỘI DUNG Định nghĩa a Hậu tố (suffix) b Trie hậu tố (suffix trie) c Cây hậu tố (suffix tree) d Mảng hậu tố (suffix array) Thuật toán ứng dụng a Thuật toán nhân đôi tiền tố b Thuật toán tìm kiếm xâu ( c Thuật toán tìm tiền tố chung dài ( ) 12 d Bài toán tìm chuỗi dài lặp lại (Longest Substring Repeated) 13 e Bài toán tìm chuỗi chung dài (Longest Common Substring) 13 ) 11 Bài tập 14 Tài liệu tham khảo 15 III KẾT LUẬN 15 3|Trang I ĐẶT VẤN ĐỀ Xử lý chuỗi từ lâu trở thành vấn đề quen thuộc, đặc biệt xâu có độ dài lớn, chẳng hạn xử lý chuỗi DNA, đoạn văn bản, từ điển, v.v… Vì vậy, việc thành lập cấu trúc liệu riêng cho xâu thuật toán để thao tác xâu vô cần thiết Trong chuyên đề này, em xin giới thiệu vài cấu trúc liệu xâu tiêu biểu hiệu hậu tố, với dạng mô khác mảng hậu tố Sức mạnh hậu tố nằm chỗ chúng biểu diễn tất hậu tố xâu cung cấp nhiều phép toán làm tảng cho thuật toán hiệu Bên cạnh đó, việc xây dựng hậu tố phức tạp tốn nhớ Trong số trường hợp, người ta lại chuộng sử dụng mảng hậu tố tính ngắn gọn xây dựng, tốn Trong kỳ thi ACM – ICPC, IOI, … tính đặc thù khống chế thời gian nên dùng mảng hậu tố thay cho hậu tố điều cần thiết Theo thời gian, nhà khoa học có nhiều đóng góp để tiến hóa cấu trúc liệu hậu tố Ban đầu Trie hậu tố, sau rút gọn lại thành hậu tố cuối mảng hậu tố Tuy nhiên, có nhiều thuật toán để hình thành trực tiếp mảng hậu tố mà không cần thông qua dùng mảng để “dựng ngược lại” cấu trúc Trong chuyên đề hôm nay, em giới thiệu sơ qua định nghĩa Trie hậu tố, Cây hậu tố Mảng hậu tố Kèm theo đó, em nói thêm giải thuật hình thành Mảng hậu tố trực tiếp dạng tập để ứng dụng 4|Trang II NỘI DUNG Định nghĩa a Hậu tố (suffix) Hậu tố i xâu xâu tính từ vị trí thứ i đến vị trí cuối xâu Ví dụ, hậu tố xâu ‘BALALAIKA’ ‘LAIKA’ (vị trí chuỗi đánh số thứ tự 0) b Trie hậu tố (suffix trie) Trie lấy từ chữ ‘Information Retrieval’ (truy hồi thông tin) Cho S tập hợp xâu Suffix Trie S gồm tất hậu tố viết từ S Cây tuân thủ vài nguyên tắc sau: - Mỗi cạnh gán nhãn ký tự - Mỗi đỉnh gán nhãn xâu hình thành cách ghép tất nhãn cạnh đường từ đỉnh gốc đến đỉnh xét - Mỗi đỉnh liên kết với tối đa 26 đỉnh (giả thiết xét chuỗi gồm ký tự tiếng Anh in hoa) - Mỗi đỉnh có thêm hai nhãn boolean để đánh dấu xâu đỉnh có phải hậu tố hay không, có phải phần tử S hay không Ví dụ, S = {‘DOG’, ‘JOG’, ‘JOB’} hậu tố bao gồm {‘DOG’, ‘JOG’, ‘JOB’, ‘OG’, ‘OB’, ‘G’, ‘B’} Hình bên mô tả Suffix Trie tập S Các đỉnh tô màu trắng mang xâu hậu tố S Các đỉnh viền đen mang xâu phần tử S Hiển nhiên xâu hậu tố nên đỉnh viền đen tô màu trắng Root B B D D G J O G J O O DO JO G DOG G JOG O G OG B OB B JOB c Cây hậu tố (suffix tree) Bây thử chuyển sang thao tác chuỗi dài để thấy rõ thiếu hiệu phân vùng liệu Trie Xét xâu S = ‘BALALAIKA$’ Ký tự cuối ‘$’ mang ý nghĩa kết thúc xâu Trong bảng mã ASCII, ký tự đứng trước ký tự ‘A’, nói cách khác, 5|Trang đứng trước tất ký tự xâu S Ký tự đảm bảo hậu tố S nằm nút Nút gán nhãn số i, mô tả hậu tố từ root đến nút trùng với hậu tố thứ i S Nếu biểu diễn Suffix Trie, thấy thiếu hiệu nằm chỗ: Xâu S dài $ root A B nhiều đỉnh bị K $ I L I lặp lại L K A i Suffix A A A BALALAIKA$ $ A K L ALALAIKA$ L I $ LALAIKA$ A L I A A K ALAIKA$ $ I LAIKA$ A K L A AIKA$ A I IKA$ K A $ $ KA$ K A A$ I A $ $ $ K A $ Suffix Tree hình thành cách “gộp” A đỉnh có nút lại KA$ $ với Như Suffix LA IKA$ IKA$ Tree cho xâu S nói BALALAIKA$ LA biểu diễn gọn gàng hình bên IKA$ Khi đó, nhãn cạnh IKA$ LAIKA$ LAIKA$ không ký tự mà chuỗi Tương tự Trie, nhãn nút chuỗi ghép chuỗi nằm cạnh từ gốc xuống nút Trong suffix tree chuỗi độ dài n, số nút (kí hiệu V) không vượt 2n Vì giả sử có m nút nhánh, nên = + Số cạnh lúc = + − tổng số nút tất nút Mà: - Nút gốc có 6|Trang $ root - Nút nhánh ngoại trừ nút gốc có - Nút Nên ⟹ ≥ 2( ≤2 − 1) + = −1⟹ + −1≥2 −1⟹ ≤ d Mảng hậu tố (suffix array) Trong Algorithmica Esko Ukkonen có trình bày cách xây dựng hậu tố ( ), nhiên phức tạp khó cài đặt kỳ thi lập trình Một thay gần hoàn hảo mảng hậu tố, thiết kế Udi Manber Gene Meyers, đơn giản nhiều so với hậu tố Gọi A tập hợp hậu tố chuỗi S, xếp mảng A theo thứ tự từ điển Với A[i] xác định hậu tố thứ SA[i] chuỗi S Như mảng SA hình thành gọi mảng hậu tố Ví dụ, S=’BALALAIKA$’ mảng hậu tố SA = {9, 8, 5, 3, 1, 0, 4, 2, 6, 7} Xem bảng đây: i SA[i] Suffix $ $ root A$ LA A AIKA$ $ 3 ALAIKA$ IKA$ IKA$ LAIKA$ ALALAIKA$ BALALAIKA$ KA$ IKA$ LA BALALAIKA$ 6 IKA$ IKA$ 7 KA$ LAIKA$ LAIKA$ LALAIKA$ Cách hình thành đơn định nghĩa mảng hậu tố Nếu dựa vào thuật toán trên, tốn ( ) cho lần so sánh, tốn ( log ) cho công việc xếp Như độ phức tạp cuối ( log ) – không chấp nhận nhiều trường hợp Trong phần chuyên đề, em xin trình bày thuật toán thành lập mảng hậu tố hiệu quả, với toán kèm Thuật toán ứng dụng a Thuật toán nhân đôi tiền tố Thuật toán dùng để lập mảng hậu tố thời gian ( log ) 7|Trang Trong giới hạn chuyên đề này, nói đến “sắp xếp”, độc giả ngầm hiểu em nói đến “sắp xếp tăng dần” theo giá trị (đối với số) theo thứ tự từ điển (đối với chuỗi) Ý tưởng thuật toán sau: - Gán hậu tố hạng (rank): hai hậu tố có ký tự đầu có hạng nhau, hậu tố có ký tự đầu nhỏ có hạng nhỏ Việc gán hạng tiến hành ( ) Hạng đại diện cho ký tự đầu hậu tố Các hậu tố xếp theo hạng đồng nghĩa với việc xếp theo ký tự - Giả sử có dãy hậu tố xếp theo k ký tự đầu tiên, thuật toán xây dựng dãy hậu tố xếp theo 2k ký tự  Mỗi hậu tố có hạng, hạng sơ cấp Để ý rằng, ta xếp k ký tự đầu, hậu tố thứ i cần xem hậu tố thứ i+k tiêu chí để xếp Vậy hậu tố thứ i cần có thêm hạng thứ cấp, hạng sơ cấp hậu tố thứ i+k Trường hợp chuỗi S hậu tố i+k (tức i+k ≥ |S|) xem hạng thứ cấp hậu tố i  Sắp xếp cặp số (, ) Trong trình xếp, vị trí hậu tố thay đổi theo cặp số Hay nói cách khác, xếp hậu tố cách gián tiếp, thông qua việc xếp cặp hạng  Sau xếp, gán lại hạng sơ cấp cho hậu tố: hai hậu tố có cặp hạng cũ hạng nhau, hậu tố có cặp hạng cũ nhỏ hạng nhỏ Bước lặp xây dựng thứ tự hậu tố xếp theo 2, 4, 8, …, ký tự Thuật toán ngưng lại hạng sơ cấp hậu tố đôi khác (tức việc xếp hậu tố hoàn toàn xác định) Có tổng cộng tối đa log bước lặp, bước lặp lại có thao tác gán hạng tốn thao tác xếp ( log ) Vậy thuật toán nhân đôi tiền tố tốn ( (log ) ) Tuy nhiên thuật toán xếp cho số nhỏ dùng đếm phân phối (counting sort) xếp số (radix sort) để giảm độ phức tạp ( ) Mô qua ví dụ S = ‘BALALAIKA$’ sau: (Để thuận tiện cho việc trình bày, em xin dùng ký tự ‘_’ để mô tả ký tự “rỗng” chuỗi.) 8|Trang - Xếp hạng ký tự Ví dụ, ký tự hậu tố gồm {$, A, B, I, K, L} tương ứng với hạng {1, 2, 3, 4, 5, 6} Hậu tố bắt đầu ký tự gán hạng sơ cấp số nguyên dương tương ứng mô tả i SA[i] Suffix BALALAIKA$ ALALAIKA$_ LALAIKA$ ALAIKA$ _ LAIKA$ AIKA$ _ IKA$ KA$ _ A$ $ _ RA[SA[i]] 5 RA[SA[i]+1] 5 - Sắp xếp lại cặp số (RA[SA[i]], RA[SA[i]+1]) i SA[i] Suffix $ _ A$ AIKA$ _ ALALAIKA$_ ALAIKA$ _ BALALAIKA$ IKA$ KA$ _ LALAIKA$ LAIKA$ RA[SA[i]] 2 2 3 5 RA[SA[i]+1] 5 2 - Đặt lại hạng sơ cấp dựa theo cặp (, ) Hai hậu tố có cặp hạng cũ hạng Hậu tố có cặp hạng cũ nhỏ hạng nhỏ Ví dụ hậu tố bảng có cặp hạng (2, 5) nên bảng chúng có hạng sơ cấp (hạng 4) i 9|Trang SA[i] Suffix $ _ A$ AIKA$ _ ALALAIKA$_ ALAIKA$ _ BALALAIKA$ IKA$ KA$ _ LALAIKA$ LAIKA$ RA[SA[i]] 4 8 RA[SA[i]+2] 0 - Sắp xếp bảng theo cặp số (, ) đặt hạng sơ cấp mới, ta có bảng đây: i SA[i] Suffix $ _ A$ AIKA$ _ ALAIKA$ _ ALALAIKA$_ BALALAIKA$ IKA$ KA$ _ LAIKA$ LALAIKA$ RA[SA[i]] 10 RA[SA[i]+2] 0 - Từ xuống dưới, 10 hạng điền đủ cho 10 hậu tố nên kết xếp cuối Mảng SA = {9, 8, 5, 3, 1, 0, 6, 7, 4, 2} mảng hậu tố, mô tả hậu tố tương ứng xếp theo thứ tự từ điển Pseudo Code sau sử dụng SA mảng hậu tố, RA[SA[i]] hạng sơ cấp hậu tố SA[i], tempSA[.] tempRA[.] hai mảng tạm thời để lưu vị trí SA RA thực counting sort radix sort Ghi chú: mảng hạng xét mảng hạng sơ cấp thứ cấp int c[N], RA[N], tempRA[N], SA[N], tempSA[N]; void countingSort(int k) { // xếp SA theo RA[i+k] fill c with zero; ∀i∈[0 n-1]: if (i+k >= n) c[0]++; else c[RA[i+k]]++; // lúc này, c[x] = số lần xuất x mảng hạng xét; ∀i∈[0 max(300,n)): { int t = c[i]; c[i] = sum; sum += t; } // lúc này, c[x] = số phần tử mảng hạng xét có giá trị nhỏ x // thứ tự xếp RA[i+k] i ∀i∈[0 n-1]: if (i+k >= n) tempSA[c[0]++] = i; else tempSA[c[RA[i+k]]++] = i; // cập nhật SA ∀i∈[0 n-1]: SA[i] = tempSA[i]; } void radixSort(int k) { countingSort(k); countingSort(0); } void construct(int k) { 10 | T r a n g ∀i∈[0 n-1]: SA[i] = i; ∀i∈[0 n-1]: RA[i] = S[i]; // tận dụng mã ASCII trở thành hạng ký tự int k = 1, r; while (k [...]... Karkkainen, Giovanni Manzini, và Simon J Puglisi c Cây hậu tố và một số ứng dụng trong xử lý xâu – Lê Minh Hoàng III KẾT LUẬN Qua quá trình thực hiện chuyên đề, em thấy mình đã có bước tiếp cận với nhiều giải thuật mới trong việc xử lý xâu Các bài tập minh họa đã chứng tỏ được kiến thức về trie hậu tố, mảng hậu tố, và cây hậu tố có ứng dụng quan trọng trong công nghệ sinh học, tìm kiếm từ, và thành lập từ điển,... trong mảng hậu tố, nói cách khác, hai hậu tố i và j nằm liền kề nhau trong thứ tự từ điển - Cho xâu S[0 n] có mảng hậu tố SA[0 n], mảng LCP[1 n] được hình thành theo nguyên tắc: LCP[j] = lcp(S[SA[j] n], S[SA[j-1] n]) (LCP[j] = tiền tố chung dài nhất của hậu tố SA[j] và hậu tố SA[j-1]) - Mảng LCP được sắp xếp lại (Permuted LCP Array) – PLCP[0 n-1] được hình thành theo nguyên tắc: PLCP[SA[j]] = LCP[j] - Mảng. .. dài nhất) - Duyệt qua mảng SA, nếu hậu tố SA[i] và SA[i – 1] thuộc hai chuỗi khác nhau thì cập nhật L = max(L, LCP[i]) Việc kiểm tra hai hậu tố thuộc hai chuỗi khác nhau rất đơn giản Nếu một số x < strlen(S1) thì hậu tố x được xem là thuộc chuỗi S1, ngược lại, hậu tố x thuộc chuỗi S2 Tại sao chúng ta chỉ quan tâm hai hậu tố kề nhau trong từ điển? Chúng ta sẽ chứng minh, khi xét hai hậu tố khác gốc không... ‘MALAI#’ và chuỗi S2 = ‘BALALAIKA$’ (ký tự kết thúc của hai chuỗi phải khác nhau — $ và #) Ghép hai chuỗi này lại để có chuỗi S = ‘MALAI#BALALAIKA$’ Trong chuyên đề này, để tiện cho việc mô tả, ta gọi gốc của một hậu tố x là chuỗi S1 nếu x < strlen(S1), là chuỗi S2 nếu x ≥ strlen(S1) Việc tìm một chuỗi con chung dài nhất của hai chuỗi S1 và S2 được tiến hành như sau: - Xây dựng mảng hậu tố, mảng LCP... PRINTER (trích từ đề thi IOI năm 2008) Hướng dẫn: Lập mảng SA và LCP, từ đó dựng Trie hậu tố Bài toán trở thành độ dài đường đi ngắn nhất để thăm tất cả các nút lá trên một cây Mỗi bước đi xuống nút con tương ứng với việc viết nhãn nút con đó ra Mỗi lần kết thúc việc thăm nút lá tương ứng với lệnh Print (‘P’) Mỗi 14 | T r a n g lần trở về nút cha, tương ứng với lệnh xóa một ký tự trong máy in (‘— ‘) 4 Tài... quy về xét hai hậu tố có khoảng cách nhỏ dần cho đến khi chúng kề nhau Xét một hậu tố SA[i] (i ≥ 2) thuộc chuỗi S2 Giả sử nó có tiền tố chung dài nhất độ dài k với một hậu tố SA[j] (j < i – 1) khác gốc của hậu tố SA[i] Do sắp xếp theo thứ tự từ điển, tiền tố chung dài nhất của hậu tố SA[j] so với một hậu tố SA[p] nào đó (j < p < i) sẽ không nhỏ hơn k Vậy sẽ có lợi hơn nếu xét giữa SA[j] và SA[p] Nếu... PLCP[SA[j]] = LCP[j] - Mảng Phi, Phi[i] mô tả tiền tố ứng trước tiền tố i trong mảng SA Dựa vào định nghĩa, có thể tính được mảng LCP: void computeLCP() { LCP[0] = 0; for (int i = 1; i < n; ++i) { int L = 0; while (T[SA[i]+L] == T[SA[i-1]+L]) ++L; LCP[i] = L; } } Như vậy, thuật toán trên có độ phức tạp ( ) Điều này đi ngược lại với mục đích dựng mảng hậu tố Chúng ta sẽ có bước tiếp cận khác Ta thừa nhận... tất cả các hậu tố từ SA[pair.first] đến SA[pair.second] đều có một tiền tố trùng với P c Thuật toán tìm tiền tố chung dài nhất trong ( ) Khái niệm: - Cho hai xâu x[0 m] và xâu y[0 n] Tiền tố chung dài nhất (Longest Common Prefix) của hai xâu x và y là số L lớn nhất sao cho x[0 L] == y[0 L] Ký hiệu: L = pcp(x, y) Nhận xét: Hậu tố i có tiền tố chung dài nhất với một hậu tố j của chuỗi S thì i và j nằm... độ dài n và mảng hậu tố SA đã được xây dựng từ S Dùng kỹ thuật tìm kiếm nhị phân trên một mảng hậu tố đã sắp xếp, chúng ta dễ tìm ra được sự tồn tại của xâu P độ dài m nào đó trên xâu S trong tối đa (log ) phép so sánh Mỗi phép so sánh xâu có độ phức tạp ( ) Như vậy thuật toán hoạt động hiệu quả với ( log ) Do xâu P có thể xuất hiện nhiều lần trong S, tức là nó sẽ là tiền tố của một dãy các hậu tố liên... khoảng cách này Lưu ý hậu tố SA[p] phải có gốc khác hậu tố SA[j] 3 Bài tập a UVa 760 – DNA Sequencing Tóm tắt: Cho hai chuỗi DNA, mỗi chuỗi được biểu diễn bằng dữ liệu kiểu string, chỉ gồm các ký tự a, t, g, c Tìm tất cả đoạn DNA chung dài nhất của hai chuỗi Hướng dẫn: Giải bằng phương pháp nêu ở II.2.e Code: http://bit.ly/22zQLnL b SPOJ – SARRAY Hướng dẫn: Bài tập thuần về mảng hậu tố Xem cách làm bằng

Ngày đăng: 10/05/2016, 16:40

Tài liệu cùng người dùng

Tài liệu liên quan