6. Bài toán về cây khung nhỏ nhất
6.3. Thuật toán Prim
Thuật toán Kruskal làm việc kém hiệu quả đối với đồ thị dày. Để khắc phục ta sử dụng thuật toán Prim (còn gọi là phương pháp lân cận gần nhất, hay “Người láng giềng gần nhất”).
Ý tưởng của thuật toán Prim
Ý tưởng của thuật toán Prim như sau: Bắt đầu từ một đỉnh s tùy ý của đồ thị, đầu tiên ta nối đỉnh s với đỉnh lân cận gần nó nhất, chẳng hạn là đỉnh y. Nghĩa là trong số các đỉnh kề đỉnh s, cạnh (s, y) có trọng số nhỏ nhất. Tiếp theo, trong số các cạnh kề với hai đỉnh s hoặc y, ta tìm cạnh có trọng số nhỏ nhất, cạnh này dẫn đến đỉnh thứ ba z, và ta thu được cây gồm ba đỉnh và hai cạnh. Quá trình này cứ tiếp tục cho đến khi ta thu được cây gồm n đỉnh và n - 1 cạnh thì nó chính là cây khung cực tiểu cần tìm.
Giả sử đồ thị cho bởi ma trận trọng số C = {c[i, j], i, j = 1, 2, …, n}. Trong quá trình thực hiện thuật toán, ở mỗi bước để có thể nhanh chóng chọn đỉnh và cạnh cần bổ sung vào cây khung, các đỉnh của đồ thị sẽ được gán nhãn. Nhãn của đỉnh v gồm hai phần và có dạng (d[v], near[v]), trong đó d[v] dùng để ghi nhận độ dài cạnh nhỏ nhất trong số các cạnh nối đỉnh v với các đỉnh của cây khung đang xây dựng (ta sẽ gọi là khoảng cách từ đỉnh v đến tập các đỉnh của cây khung), nói một cách chính xác:
còn near[v] ghi nhận đỉnh của cây khung gần v nhất (near[v] := z)
Mô phỏng thuật toán Prim trên Pascal
procedure Prim; begin (*Bước khởi tạo*) chọn s là đỉnh nào đó của đồ thị; VH := {s}; T := ∅; d[s] := 0; near[s] := s; for v ∈ V \ VH do begin d[v] := c[s, v]; near[v] := s; end; (* Bước lặp*) stop := false; while not stop do begin
Tìm đỉnh u ∈ V \ VH thỏa mãn d[u] = min {d[v] : v ∈ V \ VH} ;
VH := VH∪ {u} ; T := T ∪ {(u, near[u]} ; if |VH| = n then begin H := (VH , T ) là cây khung cực tiểu ; stop := true ; end else for v ∈ V \VH do if d[v] > c[u, v] then begin d[v] := c[u, v]; near[v] := u; end; end; end;
1 2 3 4 5 6 1 0 33 17 ∞ ∞ ∞ 2 0 18 20 ∞ ∞ 3 0 16 4 ∞ 4 0 9 8 5 0 14 C = 6 0
Bảng dưới đây ghi nhãn của các đỉnh trong các bước lặp của thuật toán, đỉnh đánh dấu * là đỉnh được chọn để bổ sung vào cây khung (khi đó nhãn của nó không bị biến đổi trong các bước tiếp theo, vì thế ta đánh dấu “-“ để ghi nhận điều đó.
Bước lặp Đỉnh 1 Đỉnh 2 Đỉnh 3 Đỉnh 4 Đỉnh 5 Đỉnh 6 VH T Khởi tạo [0, 1] [33, 1] [17, 1]* [∞, 1] [∞, 1] [∞, 1] 1 ∅ 1 - [18, 3] - [16, 3] [4, 3]* [∞, 1] 1, 3 (3, 1) 2 - [18, 3] - [9, 5]* - [14, 5] 1, 3, 5 (3,1),(5,3) 3 - [18, 3] - - - [8, 4]* 1,3,5,4 (3,1),(5,3), (4,5) 4 - [18,3]* - - - - 1,3,5,4, 6 (3,1),(5,3), (4,5),(6,4) 5 - - - - - - 1,3,5,4,6,2 (3,1),(5,3), (4,5),(6,4), (2,3) BÀI TẬP CHƯƠNG 5 1. Cho đồ thị sau:
Hãy biểu diễn đồ thị bằng a). Ma trận kề
b). Danh sách kề
2. Cho đồ thị sau
Hãy biểu diễn đồ thị bằng
3. Cho các đồ thị
Hãy minh họa các bước của thuật toán a) Tìm kiếm theo chiều sâu
b) Tìm kiếm theo chiều rộng
4. Cho đồ thị
Nêu cách sắp xếp thứ tự các đỉnh do thuật toán Topological-Sort tạo ra cho hình trên. Minh họa thuật toán.
5. Cho đồ thị
CÁC CHUYÊN ĐỀ MÔN HỌC
1. Hash table 2. Balanced Tree 3. B – Tree
4. Red – Black Trees 5. AVL Trees
6. Splay Trees 7. Skip List 8. Heap
9. Priority Queue
10. Deapth First Search, Breadth First Search 11. Shorted Path (Đường đi ngắn nhất)
12. Minimum Spanning Tree (cây khung tối thiểu) 13. Flow Network (luồng trong mạng)
14. Topological Sort 15. Probabilistic Algorithm
16. The class P, NP, and NP – complete, Co-NP (Độ phức tạp bài toán)
Ghi chú
• Chuyên đề từ 1 đến 9: đề cập đến các cấu trúc dữ liệu nâng cao: Định nghĩa cấu trúc dữ liệu trừu tượng; Các phép toán (khởi tạo, thêm, xóa, sửa, …); Các ứng dụng (những ứng dụng nào dùng nó?). Có thể tham khảo tài liệu trên wikipedia.
• Chuyên đề 13: Đề cập đến các nội dung: Luồng trong mạng; Luồng chi phí tối thiểu; Đa luồng;
• Chuyên đề từ 10 đến 14: Lưu ý đề cập đến các nội dung: Nêu bài toán cần giải quyết; Các thuật toán * (ví dụ thuật toán A*) ; Các ứng dụng. Các chuyên đề từ 1 đến 13 có thể tham khảo tài liệu “Toán rời rạc” của Nguyễn Đức Nghĩa (ĐH BK HN).
• Chuyên đề 15: Đề cập đến các nội dung: Tư tưởng chung của thuật toán là gì? Ví dụ minh họa.
• Chuyên đề 16: Đề cập đến việc chứng minh độ phức tạp của bài toán: Thế nào là lớp P (tồn tại thuật toán đa thức để giải)? lớp NP? NP-complete? (không tồn tại thuật toán đa thức để giải); Chứng minh một thuật toán thuộc lớp NP-C. Chú ý độ phức tạp thuật toán (tính O(?)) khác với độ phức tạp bài toán (Có thể giải được hay không thể giải được).