Giáo trình Toán rời rạc Chương 6

12 642 3
Giáo trình Toán rời rạc Chương 6

Đ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

Giáo trình Toán rời rạc

II. CÂY (TREE)1. Các khái niệm cơ bản:Đònh nghóa: Đồ thò vô hướng, liên thông và không chứa chu trình đơn nào gọi là cây.Vì cây không chứa chu trình đơn nên nó không thể có cạnh bội và vòng. Vì vậy cây là một đồ thò đơn.Ví dụ: (hình 1)Nếu một đồ thò vô hướng, không chứa chu trình đơn nào nhưng không liên thông thì đồ thò đó phải chứa các thành phần liên thông. Ta sẽ gọi loại đồ thò đó là rừng.Ví dụ: (Hình 2: Một rừng với 5 thành phần liên thông)Đònh lý: Một đồ thò vô hướng là một cây nếu và chỉ nếu tồn tại một đường đi duy nhất giữa mọi cặp đỉnh bất kì của nó.Chứng minh:- Giả sử đồ thò vô hướng T là một cây. Cho x và y là hai đỉnh bất kì của T. Vì T liên thông nên phải có một đường đi α từ x đến y. Nếu có một đường đi β (khác α) từ x đến y thì cặp (α,β) sẽ tạo thành một chu trình đơn. Mâu thuẩn với giả thiết T là một cây.- Ngược lại giả sử đồ thò vô hướng T thỏa tính chất tồn tại một đường đi duy nhất giữa mọi cặp đỉnh bất kì của nó. Ta suy ra được:1. T liên thông.2. Nếu tồn tại một chu trình đơn trong T. Chẳng hạn chu trình đơn chứa hai đỉnh x, y nào đó của T. Khi đó ta có hai đường đi phân biệt tách ra được từ chu trình đơn nói trên và nối x với y. Mâu thuẩn với giả thiết về tính chất của T. Vậy T không thể chứa chu trình đơn được.Vậy T là một cây.118 QED.Thuật ngữ:Ta qui ước gọi cây không có đỉnh nào là cây rỗng (empty tree). Trong phần lớn các ứng dụng về cây, một đỉnh đặc biệt của cây được gọi là gốc (roof | root). Khi đã xác đỉnh một đỉnh của cây là gốc thì ta có thể xác đònh hướng cho từng cạnh như sau: Vì có một đường đi duy nhất từ gốc đến mọi đỉnh của đồ thò nên ta đònh hướng cho từng cạnh theo hướng từ gốc đi ra. Đỉnh nào từ đó không có một cạnh đi ra nữa thì gọi là một lá. Các đỉnh của cây không phải là lá gọi là đỉnh trong. Nếu v là một đỉnh của cây T mà không phải là gốc thì cha (parent) của v là đỉnh (duy nhất) u sao cho cho có cạnh nối từ u đến v (có vẻ như gọi v là con (child) của u cũng hợp lí !). Các đỉnh có cùng một cha sẽ được gọi là các đỉnh anh em(siblings). Tổ tiên (ancestors) của một đỉnh là mọi đỉnh trên đường đi từ gốc (kể cả gốc) đến đỉnh đó loại trừ đỉnh đó. Nếu b là con của a thì đồ thò con của cây đó gồm b và mọi con cháu của b cùng tất cả các cạnh liên hệ với các con cháu của b gọi là một cây con ứng với đỉnh a.Cây mà mỗi đỉnh trừ các lá đều có đúng m con gọi là cây m-phân chính xác. Cây 2-phân chính xác gọi là cây nhò phân (binary tree). Trong cây nhò phân thì trong hai đỉnh anh em bất kì sẽ có một đỉnh gọi là em bên trái (left sibling), đỉnh còn lại gọi là em bên phải (right sibling)Đònh lý: Một cây có n đỉnh sẽ có (n-1) cạnh.Chứng minh (tầm thường).QEDĐònh lý: Một cây m-phân chính xác với i đỉnh trong có mi+1 đỉnh.Chứng minh:Vì đỉnh nào trong số i đỉnh trong cũng có đúng m đỉnh con. Suy ra cây có mi đỉnh không phải là đỉnh gốc. Vậy tổng số đỉnh của cây m-phân chính xác làø mi+1.QEDo Một số ứng dụng: Cây được sử dụng trong rất nhiều lónh vực, đặc biệt là trong các mô hình liên quan đến cấu trúc tổ chức của các đối tượng đang được xét đến:119 o Hệ thống folder trong các máy tính: Người ta tổ chức quản lí tài nguyên của hệ thống máy tính theo các folder. Mỗi folder có thể chứa các folder con hoặc không. Loại folder không thể chứa các folder con gọi là các file. Một Folder gốc chứa toàn bộ các folder khác gọi là Desktop . Trong hình trên là một phần hình ảnh trích từ giao diện của Windows Explorer (MicroSoft Windows 98). Một nhánh của cây quản lí tài nguyên trên là:DesktopMy Computer My DocumentsA:\ C:\Hp_xtra RegisterSku.11 t_drive.GDIo Cây tìm kiếm nhò phân.Bài toán tìm kiếm các mục thông tin trong một danh sách là một trong các bài toán quan trọng của tin học. Thuật toán tìm kiếm sẽ có hiệu quả nhất khi các mục thông tin đó được sắp xếp có thứ tự. Trong trường hợp các mục thông tin đó được sắp xếp theo các đỉnh của của 120 một cây nhò phân thì mỗi đỉnh sẽ được gán cho một khóa sao cho khóa của mỗi đỉnh đều lớn hơn bất kì khóa nào của các đỉnh thuộc cây con bên trái của đỉnh đó và nhỏ hơn bất kì khóa nào của các đỉnh thuộc cây con bên phải của đỉnh đó.Giải thuật xây dựng các mục thông tin trên cây nhò phân có thể được phát biểu một cách đệ qui như sau:Bắt đầu với một cây chỉ chứa một đỉnh (tức là gốc). Mục thứ nhất trong danh sách sẽ được gán làm khóa cho gốc đó. Để bổ sung một mục thông tin mới, trước hết so sánh nó với các khóa của các đỉnh đã có trên cây, bắt đầu từ gốc đi sang trái nếu mục thông tin đó có khóa bé hơn khóa của khóa của đỉnh tương ứng khi đỉnh này có con bên trái, hoặc đi sang phải nếu mục thông tin đó có khóa lớn hơn khóa của khóa của đỉnh tương ứng khi đỉnh này có con bên phải. Khi mục thông tin đó có khóa bé hơn khóa của đỉnh tương ứng và đỉnh đó không có con bên trái thì một con bên trái của đỉnh này được đưa vào (với khóa của mục thông tin này). Tương tự, khi mục thông tin đó có khóa lớn hơn khóa của đỉnh tương ứng và đỉnh đó không có con bên phải thì một con bên phải của đỉnh này được đưa vào (với khóa của mục thông tin này). Ví dụ:Ví dụ trên, theo thứ tự từ trái qua phải và từ trên xuống, cho thấy quá trình xây dựng cây nhò phân tìm kiếm cho các từ khóa Huong, Bang, Luu, Dung, Kiet, Hung, Quan, Thuy đã diễn ra như thế nào.Giải thuật sau đây cho phép ta đònh vò một mục thông tin nếu nó đã có mặt trong cây tìm kiếm nhò phân hoặc bổ sung một đỉnh mới có khóa là mục thông tin này nếu nó chưa có mặt trên cây này:121 Procedure BinarySearch (T: cây tìm kiếm nhò phân; X: khóa của mục thông tin);{Đỉnh không có trong T có giá trò Null}v:= Gốc của TWhile (v ≠ Null) và (Khóa(v)≠X)BEGINIF x < Khóa(v) THENIF (Con bên trái của v ≠ Null) THEN v := Con bên trái của vELSE Thêm đỉnh mới u là con bên trái của v và gán v:= NullELSEIF (Con bên phải của v ≠ Null) THEN v:= Con bên phải của vELSE Thêm đỉnh mới u là con bên phải của v và gán v:= NullENDIF (Gốc cuả T = Null) THEN Thêm đỉnh r vào cây và gán cho nó khóa XELSE IF (Khóa(v)≠x) THEN Gán cho đỉnh mới u khóa XELSE Return(v)o Cây quyết đònh.Cây có gốc, trong đó mỗi đỉnh tương ứng với một quyết đònh và mỗi cây con của cây này tương ứng với một phương án có thể có của một quyết đònh. Những lời giải có thể có của bài toán tương ứng với các đường đi tới các lá.o Mã Huffman.Giả sử ta muốn gởi một thông báo bao gồm một dãy các kí tự. Trong mỗi thông báo các kí tự là độc lập với nhau và xuất hiện với xác suất đã biết tại bất kì vò trí nào của thông báo. Chẳng hạn, ta muốn gởi một thông báo chỉ gồm 5 kí tự a, b, c, d, e với xác suất xuất hiện lần lượt là 0.12, 0.4, 0.15, 0.08, 0.25. Ta muốn mã hóa các kí tự đó bằng mã nhò phân 0 và 1 sao cho không có mã hóa của kí tự nào là phần đầu (ie: trùng với) của mã hóa của các kí tự còn lại (Gọi là điều kiện tiền tố). Ví dụ1 ta có hai cách mã hóa sau đây:Kí tự Xác suất Code 1 Code 2 a 0.12 000 000b 0.40 001 11c 0.15 010 01d 0.08 011 001e 0.25 100 10Với Code 1 để thông báo chuỗi bcd ta cần gởi đi 001 010 011 còn đối với Code 2 ta chỉ cần gởi đi 1101001 (ngắn hơn!). Tuy nhiên khác với dùng bộ mã Code 1, ở nơi nhận ta không thể xắt lát chuỗi 1101001 để được bảng rõ bcd nếu việc truyền nhận chưa kết thúc trừ khi Code 2 thỏa điều kiện đã nêu!1 Ví dụ này dẫn từ: Data Structures and Algorithms - ALFRED V. AHO; JOHN E. HOPCROFT; JEFFREY D. ULLMAN - Addison Wesley Publishing Company (Corrections April, 1987) - pp 94-98.122 Bài toán đặt ra là: Cho một tập hợp các kí tự và xác suất xuất hiện của chúng trong văn bản. Tìm cách mã hóa bộ kí tự đó sao cho chúng thỏa điều kiện tiền tố và độ dài trung bình của mã là nhỏ nhất (tức là thời gian truyền của thông báo sẽ nhỏ nhất). Trong ví dụ trên Code 1 và code 2 đều thỏa điều kiện tiền tố nhưng độ dài trung bình của mã trong Code 1 là 3 trong khi độ dài trung bình của mã trong Code 2 chỉ có (3*0.12+2*0.4+2*0.15+3*0.08+2*0.25) = 2.2. Vậy Code 2 phải là tối ưu chưa? Nếu xem mỗi kí tự là một nút trong một cây có trọng số, ta sẽ xây dựng một bộ mã mà độ dài trung bình của bộ mã chỉ là 2.15 như sau:Giải thuật Huffman:Lấy u là kí tự có xác xuất xuất hiện nhỏ nhất.WHILE (còn kí tự chưa xét đến) DOBeginLấy v là kí tự có xác suất xuất hiện nhỏ nhất trong các kí tự còn lại.Tạo ra một nút mới x với con bên trái là u, con bên phải là vThay u bởi x với trọng số là tổng trọng số của u và vXóa vEndQuá trình xây dựng cây mã Huffman của bộ mã trong ví dụ trên:Với cách mã hóa này ta được:123 Kí tự Xác suất Code 3 a 0.12 1110b 0.40 0c 0.15 110d 0.08 1111e 0.25 10Độ dài trung bình của bộ mã là: (4*0.12+1*0.40+3*0.15+4*0.08+2*0.25)=2.15Khi đó thông điệp bcd được truyền nhận là: 011011112o Duyệt cây: Xét biểu thức số học: (x -y)*z+(x-t)+x*z/t. Biểu thức số học này có thể được biểu diễn dưới dạng một cây nhò phân như sau:Theo cách biểu diễn này thì ta xử lý cây như sau: Nếu nút là toán hạng thì ta sẽ xác đònh giá trò toán hạng đó, nếu nút là toán tử thì ta thực hiện phép toán tương ứng với giá trò của các cây con tương ứng với nút đó. Ta thấy ngay rằng thứ tự xử lí các nút của cây là rất quan trọng vì lẽ ta không thể xử lý một nút nếu chưa xử lý các cây con tương ứng với nút đó. Phép xử lí các nút của cây sao cho mỗi nút đều được “thăm” qua một lần (và chỉ một lần thôi!) một cách có hệ thống được gọi là phép duyệt cây.Giải thuật:Sau đây là ba cách duyệt cây được đònh nghóa một cách đệ qui:Duyệt theo thứ tự trước NLR (Preorder traversal: Node - Left -Right).- Thăm gốc2 Trong trường hợp này độ dài của thông báo cũng không khác với trường hợp dùng bộ mã Code 2. Tuy nhiên nên lưu ý là độ dài trung bình của bộ mã là độ dài tính theo xác suất, đúng với trường hợp độ dài của thông báo là khá lớn (luật số lớn).124 - Duyệt cây con trái theo thứ tự trước.- Duyệt cây con phải theo thứ tự trước.Duyệt theo thứ tự giữa LNR (Inorder traversal: Left - Node -Right).- Duyệt cây con trái theo thứ tự giữa.- Thăm gốc- Duyệt cây con phải theo thứ tự giữa.Duyệt theo thứ tự sau LRN (Postorder traversal: Left - Right-Node).- Duyệt cây con trái theo thứ tự sau.- Duyệt cây con phải theo thứ tự sau.- Thăm gốcKhi gặp cây rỗng thì “thăm” có nghóa là không làm gì cả.Sau đây là mã giả tương ứng với phép duyệt cây theo thứ tự giữa:Procedure INORDER (T: Cây nhò phân)IF T ≠ Null THENBeginINORDER(Cây con bên trái của T)In ra giá trò của nút TINORDER(Cây con bên phải của T)EndELSE Return()Mã giả đối với hai phép duyệt còn lại đề nghò người đọc tự xây dựng.Vậy đối với cây nhò phân tương ứng với biểu thức số học (x -y)*z+(x-t)+x*z/t thứ tự các nút được thăm trong các phép duyệt là:a) Theo NLR:+ + * - x y z - x t / * x z t (Biểu thức dạng tiền tố.)b) Theo LNR:x - y * z + x - t + x * z / t (Biểu thức dạng trung tố)c) Theo LRN:x y - z * x t - + x z * t / + (Biểu thức dạng hậu tố)Dạng biểu thức trung tố là dạng hay dùng nhất trong toán học. Tuy nhiên để tính biểu thức viết theo dạng này ta cần phải bổ sung vào biểu thức các cặp dấu ngoặc và phải qui đònh thứ tự ưu tiên thực hiện các toán tử:* Các biểu thức con trong cặp ngoặc trong cùng được thực hiện trước tiên.* Các phép toán * và / có cùng mức ưu tiên.* Các phép toán + và - có cùng mức ưu tiên.* Trên một dãy các phép tính có cùng mức ưu tiên thì việc thực hiện các phép tính được thực hiện từ trái qua phải.Ví dụ: Xử lí biểu thức dạng trung tố: 7 - 2 * 3 + 7 - 4 + 7 * 3 / 3Việc bổ sung các cặp ngoặc để làm rõ thứ tự các cây con là cần thiết. Chẳng hạn:125 (7 - 2) * 3 + (7 - 4) + 7 * 3 / 3Kết quả sau các phép tính lần lượt là:5*3 + 3 + 7*3/315 + 3 + 7*3/315 + 3 + 21 /315 + 3 + 718 + 725Việc qui đònh thứ tự ưu tiên khi thực hiện các phép tính trong một biểu thức như vậy làm cho việc xử lí biểu thức trở nên hết sức nhiêu khê!Dạng biểu thức hậu tố là dạng biểu thức mà việc thực hiện các phép tính dễ dàng hơn: Cứ đọc các kí hiệu (token) từ trái sang phải. Khi nào gặp token là toán hạng thì ghi nhớ3 và đọc token kế tiếp. Khi nào gặp token là toán tử thì thực hiện phép tính cho hai toán hạng vừa duyệt qua gần nhất tương ứng với toán tử đó. Cách xử lí theo phương pháp này không cần bổ sung các cặp ngoặc lẫn qui đònh về mức ưu tiên của các toán tử.Ví dụ: Xử lí biểu thức dạng hậu tố: 7 2 - 3 * 7 4 - + 7 3 * 3 / +Ta lần lượt thực hiện (từ trái qua phải):7 2 - được kết quả 55 3 * được kết quả 1515 7 4 - được kết quả 15 315 3 + được kết quả 1818 7 3 * được kết quả 18 2118 21 3 / được kết quả 18 718 7 + được kết quả 25Do quá trình xử lí dạng hậu tố thuận tiện như vậy nên đây là dạng biểu thức sẽ được dùng chủ yếu để lưu trữ các biểu thức số học và xử lí các biểu thức đó bên trong các máy tính.Có thể thấy ngay rằng xử lí biểu thức dạng tiền tố cũng tương tự như xử lí biểu thức dạng hậu tố chỉ khác ở chổ phải duyệt biểu thức từ phải sang trái.Phần trình bày trên cho thấy cách duyệt một cây nhò phân. Trong cả ba cách đó ta đều lần đến các nút của cây dọc theo chiều sâu của cây và do đó được gọi là phép duyệt theo chiều sâu (Depth-First traversal). Trường hợp một đồ thò nói chung cũng đặt ra vấn đề tương tự như vậy:Procedure DepthFirstTraversal (G: Dothi; v:một nút của G)IF (v≠Null) THEN BeginThăm(v); FOR (Mỗi đỉnh u lân cận của v) DO IF (u chưa được thăm) THEN DepthFirstTraversal (G, u)3 Để thực hiện việc ghi nhớ này thông thường người ta dùng cấu trúc dữ liệu kiểu STACK - Sinh viên sẽ được nghiên cứu về cấu trúc này trong môn Cấu trúc dữ liệu và giải thuật.126 EndElse Return()Giải thuật này đảm bảo thăm được tất cả các đỉnh của G với tới được từ v (ie: liên thông với v). Vậy giải thuật có thể dùng để xác đònh một đồ thò G có liên thông hay không và xác đònh được các thành phần liên thông của G.o Giải thuật quay lui (BackTracking): Thuật toán quay lui liên quan đến việc tìm kiếm đường đi trên một đồ thò. Thực chất của phương pháp này là vét dần4 các khả năng có thể có ở mỗi bước tiếp cận với đường đi. ƠÛ mỗi bước tiếp cận ta sẽ đánh dấu đoạn đường vừa đi qua được. Nếu ở bước nào đó bò dẫn vào ngỏ cụt thì ta đánh dấu vò trí đó và quay lại vò trí trước đó một bước để lựa chọn phương án khả dó khác còn chưa xét đến. Hãy xét bài toán tìm đường đi trong một mê cung như sau:5Mê cung được biểu diễn dưới dạng một đồ thò. Mỗi nút là một ngã rẽ. Các ngã rẽ được đánh chỉ số để dễ phân biệt. Để tìm đường đi bắt đầu từ “Cửa vào” cứ mỗi lần đứng trước một ngã rẽ chúng ta sẽ đánh dấu ngã rẽ đó và chọn một trong những con đường có khả năng đi đến ngã rẽ kế tiếp. Thao tác này luôn dẫn chúng ta đến hoặc “Cửa ra” hoặc một ngã rẽ kế tiếp mà chưa đi qua hoặc dẫn chúng ta đến một ngỏ cụt (là ngã rẽ mà không cho phép đi tiếp). Nếu thao tác dẫn chúng ta đến một ngỏ cụt thì chúng ta sẽ lùi lại ngãõ rẽ vừa đi qua trước đó và lại lựa chọn một trong số các ngã rẽ còn lựa chọn được từ ngã rẽ này.Như vậy để băng qua mê cung chúng ta cần phải lần lượt đi qua một con đường gồm một số các ngã rẽ:x=(x0,x1,x2,x3, .,xn) trong đó x0=”Cửa vào” và “xn=”Cửa ra”4 Hãy phân biệt thuật ngữ “vét dần” với thuật ngữ “vét cạn”. Trong trường hợp này có khả năng ta chưa phải vét hết các con đường khi đã tìm được rồi đường đi thích hợp. Mặt khác với một số điều kiện thích hợp có thể không cần xét đến một số ngã rẽ (loại bỏ nhánh cận).5 Ví dụ này dẫn từ: Giải một bài toán trên máy tính như thế nào - HOÀNG KIẾM - Nxb Giáo dục (tái bản lần 2 - 2003) - Tập 2: Chương 4: Phương pháp thử sai - 1.3 Nguyên lí mê cung (từ trang 20 đến trang 28).127 [...]... ngã rẽ [9] đã được đánh dấu đi qua rồi Ta có thể chọn x5 là [7]và đánh dấu [7] đã được đi qua Tương tự, chọn x6 là [11]và đánh dấu [11] đã được đi qua, x7 là [10] và đánh dấu [10] đã được đi qua Tại x7 ta không có khả năng lựa chọn nào nữa mà x7 vẫn chưa phải là cửa ra do đó phải quay lại x6 để lựa x7 là [12], ) Như vậy tại mỗi bước ta phải xét toàn bộ các khả năng tại bước đó để không bỏ sót bất kì... ngã rẽ ghi trong dấu ngoặc vuông Thứ tự duyệt các nút (ngã rẽ) ghi trong dấu ngoặc tròn Thứ tự “tiến tới” hoặc “quay lui” cho bởi dãy x1, x2, x3, x4, x5 Có hai lời giải: a) [1] [2] [3] [4] [5] [6] b) [1] [2] [5] [6]  129 ...Hình trên cho ta thấy một trong những con đường băng qua mê cung: [Cửa vào] [3] [4] [9] [8] [12] [ 16] [17] [Cửa ra] Vấn đề là khi ta đã đến bước thứ xi-1 thì ta cũng không chắc rằng (i-1) thành phần này liệu có phải là một bộ phận của lời giải hay không! Vì vậy ta cần phải đánh dấu tất cả các ngã rẽ . như sau: Nếu nút là toán hạng thì ta sẽ xác đònh giá trò toán hạng đó, nếu nút là toán tử thì ta thực hiện phép toán tương ứng với giá. tìm kiếm nhò phân.Bài toán tìm kiếm các mục thông tin trong một danh sách là một trong các bài toán quan trọng của tin học. Thuật toán tìm kiếm sẽ có hiệu

Ngày đăng: 13/11/2012, 16:19

Từ khóa liên quan

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

Tài liệu liên quan