Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 332 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
332
Dung lượng
12,35 MB
Nội dung
LÊ MINH HOÀNG BÀI GIẢNG CHUYÊN ĐỀ: GIẢI THUẬT VÀ LẬP TRÌNH Bài giảng chuyên đề Đại học Sư phạm Hà Nội, 1999-2002 Try not to become a man of success but rather to become a man of value Albert Einstein i MỤC LỤC PHẦN BÀI TOÁN LIỆT KÊ §1 NHẮC LẠI MỘT SỐ KIẾN THỨC ĐẠI SỐ TỔ HỢP 1.1 CHỈNH HỢP LẶP 1.2 CHỈNH HỢP KHÔNG LẶP 1.3 HOÁN VỊ 1.4 TỔ HỢP §2 PHƯƠNG PHÁP SINH (GENERATION) 2.1 SINH CÁC DÃY NHỊ PHÂN ĐỘ DÀI N 2.2 LIỆT KÊ CÁC TẬP CON K PHẦN TỬ 2.3 LIỆT KÊ CÁC HOÁN VỊ §3 THUẬT TỐN QUAY LUI 12 3.1 LIỆT KÊ CÁC DÃY NHỊ PHÂN ĐỘ DÀI N 12 3.2 LIỆT KÊ CÁC TẬP CON K PHẦN TỬ 13 3.3 LIỆT KÊ CÁC CHỈNH HỢP KHÔNG LẶP CHẬP K 15 3.4 BÀI TỐN PHÂN TÍCH SỐ 16 3.5 BÀI TOÁN XẾP HẬU 18 §4 KỸ THUẬT NHÁNH CẬN 24 4.1 BÀI TOÁN TỐI ƯU 24 4.2 SỰ BÙNG NỔ TỔ HỢP 24 4.3 MƠ HÌNH KỸ THUẬT NHÁNH CẬN 24 4.4 BÀI TOÁN NGƯỜI DU LỊCH 25 4.5 DÃY ABC 27 PHẦN CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT 33 §1 CÁC BƯỚC CƠ BẢN KHI TIẾN HÀNH GIẢI CÁC BÀI TOÁN TIN HỌC 34 1.1 XÁC ĐỊNH BÀI TOÁN 34 1.2 TÌM CẤU TRÚC DỮ LIỆU BIỂU DIỄN BÀI TOÁN 34 1.3 TÌM THUẬT TỐN 35 1.4 LẬP TRÌNH 37 1.5 KIỂM THỬ 37 1.6 TỐI ƯU CHƯƠNG TRÌNH 38 §2 PHÂN TÍCH THỜI GIAN THỰC HIỆN GIẢI THUẬT 40 2.1 GIỚI THIỆU 40 2.2 CÁC KÝ PHÁP ĐỂ ĐÁNH GIÁ ĐỘ PHỨC TẠP TÍNH TỐN 40 2.3 XÁC ĐỊNH ĐỘ PHỨC TẠP TÍNH TỐN CỦA GIẢI THUẬT 42 2.4 ĐỘ PHỨC TẠP TÍNH TỐN VỚI TÌNH TRẠNG DỮ LIỆU VÀO 45 2.5 CHI PHÍ THỰC HIỆN THUẬT TỐN 46 ii §3 ĐỆ QUY VÀ GIẢI THUẬT ĐỆ QUY 50 3.1 KHÁI NIỆM VỀ ĐỆ QUY 50 3.2 GIẢI THUẬT ĐỆ QUY 50 3.3 VÍ DỤ VỀ GIẢI THUẬT ĐỆ QUY 51 3.4 HIỆU LỰC CỦA ĐỆ QUY .55 §4 CẤU TRÚC DỮ LIỆU BIỂU DIỄN DANH SÁCH 58 4.1 KHÁI NIỆM DANH SÁCH 58 4.2 BIỂU DIỄN DANH SÁCH TRONG MÁY TÍNH 58 §5 NGĂN XẾP VÀ HÀNG ĐỢI 64 5.1 NGĂN XẾP (STACK) .64 5.2 HÀNG ĐỢI (QUEUE) .66 §6 CÂY (TREE) 70 6.1 ĐỊNH NGHĨA 70 6.2 CÂY NHỊ PHÂN (BINARY TREE) 71 6.3 BIỂU DIỄN CÂY NHỊ PHÂN 73 6.4 PHÉP DUYỆT CÂY NHỊ PHÂN 74 6.5 CÂY K_PHÂN 76 6.6 CÂY TỔNG QUÁT 77 §7 KÝ PHÁP TIỀN TỐ, TRUNG TỐ VÀ HẬU TỐ 79 7.1 BIỂU THỨC DƯỚI DẠNG CÂY NHỊ PHÂN 79 7.2 CÁC KÝ PHÁP CHO CÙNG MỘT BIỂU THỨC 79 7.3 CÁCH TÍNH GIÁ TRỊ BIỂU THỨC 79 7.4 CHUYỂN TỪ DẠNG TRUNG TỐ SANG DẠNG HẬU TỐ 83 7.5 XÂY DỰNG CÂY NHỊ PHÂN BIỂU DIỄN BIỂU THỨC 86 §8 SẮP XẾP (SORTING) 87 8.1 BÀI TOÁN SẮP XẾP 87 8.2 THUẬT TOÁN SẮP XẾP KIỂU CHỌN (SELECTIONSORT) .89 8.3 THUẬT TOÁN SẮP XẾP NỔI BỌT (BUBBLESORT) 90 8.4 THUẬT TOÁN SẮP XẾP KIỂU CHÈN 90 8.5 SHELLSORT 92 8.6 THUẬT TOÁN SẮP XẾP KIỂU PHÂN ĐOẠN (QUICKSORT) 93 8.7 THUẬT TOÁN SẮP XẾP KIỂU VUN ĐỐNG (HEAPSORT) 99 8.8 SẮP XẾP BẰNG PHÉP ĐẾM PHÂN PHỐI (DISTRIBUTION COUNTING) 102 8.9 TÍNH ỔN ĐỊNH CỦA THUẬT TỐN SẮP XẾP (STABILITY) 103 8.10 THUẬT TOÁN SẮP XẾP BẰNG CƠ SỐ (RADIX SORT) 104 8.11 THUẬT TOÁN SẮP XẾP TRỘN (MERGESORT) 109 8.12 CÀI ĐẶT .112 8.13 ĐÁNH GIÁ, NHẬN XÉT 119 §9 TÌM KIẾM (SEARCHING) 124 9.1 BÀI TỐN TÌM KIẾM 124 9.2 TÌM KIẾM TUẦN TỰ (SEQUENTIAL SEARCH) .124 9.3 TÌM KIẾM NHỊ PHÂN (BINARY SEARCH) 124 9.4 CÂY NHỊ PHÂN TÌM KIẾM (BINARY SEARCH TREE - BST) .125 iii 9.5 PHÉP BĂM (HASH) 130 9.6 KHỐ SỐ VỚI BÀI TỐN TÌM KIẾM 130 9.7 CÂY TÌM KIẾM SỐ HỌC (DIGITAL SEARCH TREE - DST) 131 9.8 CÂY TÌM KIẾM CƠ SỐ (RADIX SEARCH TREE - RST) 134 9.9 NHỮNG NHẬN XÉT CUỐI CÙNG 139 PHẦN QUY HOẠCH ĐỘNG 141 §1 CƠNG THỨC TRUY HỒI 142 1.1 VÍ DỤ 142 1.2 CẢI TIẾN THỨ NHẤT 143 1.3 CẢI TIẾN THỨ HAI 144 1.4 CÀI ĐẶT ĐỆ QUY 145 §2 PHƯƠNG PHÁP QUY HOẠCH ĐỘNG 147 2.1 BÀI TOÁN QUY HOẠCH 147 2.2 PHƯƠNG PHÁP QUY HOẠCH ĐỘNG 147 §3 MỘT SỐ BÀI TỐN QUY HOẠCH ĐỘNG 151 3.1 DÃY CON ĐƠN ĐIỆU TĂNG DÀI NHẤT 151 3.2 BÀI TOÁN CÁI TÚI 156 3.3 BIẾN ĐỔI XÂU 158 3.4 DÃY CON CÓ TỔNG CHIA HẾT CHO K 162 3.5 PHÉP NHÂN TỔ HỢP DÃY MA TRẬN 166 3.6 BÀI TẬP LUYỆN TẬP 170 PHẦN CÁC THUẬT TOÁN TRÊN ĐỒ THỊ 175 §1 CÁC KHÁI NIỆM CƠ BẢN .176 1.1 ĐỊNH NGHĨA ĐỒ THỊ (GRAPH) 176 1.2 CÁC KHÁI NIỆM 177 §2 BIỂU DIỄN ĐỒ THỊ TRÊN MÁY TÍNH 179 2.1 MA TRẬN KỀ (ADJACENCY MATRIX) 179 2.2 DANH SÁCH CẠNH (EDGE LIST) 180 2.3 DANH SÁCH KỀ (ADJACENCY LIST) 181 2.4 NHẬN XÉT 182 §3 CÁC THUẬT TỐN TÌM KIẾM TRÊN ĐỒ THỊ 184 3.1 BÀI TOÁN 184 3.2 THUẬT TỐN TÌM KIẾM THEO CHIỀU SÂU (DEPTH FIRST SEARCH) 185 3.3 THUẬT TỐN TÌM KIẾM THEO CHIỀU RỘNG (BREADTH FIRST SEARCH) 187 3.4 ĐỘ PHỨC TẠP TÍNH TỐN CỦA BFS VÀ DFS 190 §4 TÍNH LIÊN THƠNG CỦA ĐỒ THỊ 191 4.1 ĐỊNH NGHĨA 191 4.2 TÍNH LIÊN THƠNG TRONG ĐỒ THỊ VÔ HƯỚNG 192 iv 4.3 ĐỒ THỊ ĐẦY ĐỦ VÀ THUẬT TOÁN WARSHALL 192 4.4 CÁC THÀNH PHẦN LIÊN THÔNG MẠNH 195 §5 VÀI ỨNG DỤNG CỦA DFS BFS 206 5.1 XÂY DỰNG CÂY KHUNG CỦA ĐỒ THỊ 206 5.2 TẬP CÁC CHU TRÌNH CƠ SỞ CỦA ĐỒ THỊ 209 5.3 BÀI TOÁN ĐỊNH CHIỀU ĐỒ THỊ 209 5.4 LIỆT KÊ CÁC KHỚP VÀ CẦU CỦA ĐỒ THỊ 213 §6 CHU TRÌNH EULER, ĐƯỜNG ĐI EULER, ĐỒ THỊ EULER 216 6.1 BÀI TOÁN CÁI CẦU 216 6.2 ĐỊNH NGHĨA 216 6.3 ĐỊNH LÝ 216 6.4 THUẬT TỐN FLEURY TÌM CHU TRÌNH EULER 217 6.5 CÀI ĐẶT 218 6.6 THUẬT TOÁN TỐT HƠN 220 §7 CHU TRÌNH HAMILTON, ĐƯỜNG ĐI HAMILTON, ĐỒ THỊ HAMILTON 223 7.1 ĐỊNH NGHĨA 223 7.2 ĐỊNH LÝ 223 7.3 CÀI ĐẶT 224 §8 BÀI TOÁN ĐƯỜNG ĐI NGẮN NHẤT 228 8.1 ĐỒ THỊ CÓ TRỌNG SỐ .228 8.2 BÀI TOÁN ĐƯỜNG ĐI NGẮN NHẤT 228 8.3 TRƯỜNG HỢP ĐỒ THỊ KHƠNG CĨ CHU TRÌNH ÂM - THUẬT TOÁN FORD BELLMAN 230 8.4 TRƯỜNG HỢP TRỌNG SỐ TRÊN CÁC CUNG KHƠNG ÂM - THUẬT TỐN DIJKSTRA 232 8.5 THUẬT TOÁN DIJKSTRA VÀ CẤU TRÚC HEAP .235 8.6 TRƯỜNG HỢP ĐỒ THỊ KHƠNG CĨ CHU TRÌNH - SẮP XẾP TÔ PÔ 238 8.7 ĐƯỜNG ĐI NGẮN NHẤT GIỮA MỌI CẶP ĐỈNH - THUẬT TOÁN FLOYD 241 8.8 NHẬN XÉT .243 §9 BÀI TOÁN CÂY KHUNG NHỎ NHẤT 248 9.1 BÀI TOÁN CÂY KHUNG NHỎ NHẤT 248 9.2 THUẬT TOÁN KRUSKAL (JOSEPH KRUSKAL - 1956) 248 9.3 THUẬT TOÁN PRIM (ROBERT PRIM - 1957) 253 §10 BÀI TỐN LUỒNG CỰC ĐẠI TRÊN MẠNG 257 10.1 CÁC KHÁI NIỆM 257 10.2 MẠNG THẶNG DƯ VÀ ĐƯỜNG TĂNG LUỒNG 260 10.3 THUẬT TOÁN FORD-FULKERSON (L.R.FORD & D.R.FULKERSON - 1962) .263 10.4 THUẬT TOÁN PREFLOW-PUSH (GOLDBERG - 1986) 267 10.5 MỘT SỐ MỞ RỘNG 273 §11 BÀI TỐN TÌM BỘ GHÉP CỰC ĐẠI TRÊN ĐỒ THỊ HAI PHÍA 280 11.1 ĐỒ THỊ HAI PHÍA (BIPARTITE GRAPH) 280 11.2 BÀI TOÁN GHÉP ĐÔI KHÔNG TRỌNG VÀ CÁC KHÁI NIỆM .280 11.3 THUẬT TOÁN ĐƯỜNG MỞ .281 11.4 CÀI ĐẶT .282 v §12 BÀI TỐN TÌM BỘ GHÉP CỰC ĐẠI VỚI TRỌNG SỐ CỰC TIỂU TRÊN ĐỒ THỊ HAI PHÍA - THUẬT TỐN HUNGARI 288 12.1 BÀI TỐN PHÂN CƠNG 288 12.2 PHÂN TÍCH 288 12.3 THUẬT TOÁN 289 12.4 BÀI TỐN TÌM BỘ GHÉP CỰC ĐẠI VỚI TRỌNG SỐ CỰC ĐẠI TRÊN ĐỒ THỊ HAI PHÍA 297 12.5 NÂNG CẤP 298 §13 BÀI TỐN TÌM BỘ GHÉP CỰC ĐẠI TRÊN ĐỒ THỊ .304 13.1 CÁC KHÁI NIỆM 304 13.2 THUẬT TOÁN EDMONDS (1965) 305 13.3 THUẬT TOÁN LAWLER (1973) 307 13.4 CÀI ĐẶT 309 13.5 ĐỘ PHỨC TẠP TÍNH TỐN 313 TÀI LIỆU ĐỌC THÊM 315 vi HÌNH VẼ Hình 1: Cây tìm kiếm quay lui toán liệt kê dãy nhị phân .13 Hình 2: Xếp quân hậu bàn cờ 8x8 .19 Hình 3: Đường chéo ĐB-TN mang số 10 đường chéo ĐN-TB mang số 19 Hình 4: Lưu đồ thuật giải (Flowchart) 36 Hình 5: Ký pháp Θ lớn, Ο lớn Ω lớn 41 Hình 6: Tháp Hà Nội .54 Hình 7: Cấu trúc nút danh sách nối đơn 59 Hình 8: Danh sách nối đơn 59 Hình 9: Cấu trúc nút danh sách nối kép 61 Hình 10: Danh sách nối kép 61 Hình 11: Danh sách nối vòng hướng 61 Hình 12: Danh sách nối vịng hai hướng .62 Hình 13: Dùng danh sách vịng mơ tả Queue 67 Hình 14: Di chuyển toa tàu 69 Hình 15: Di chuyển toa tàu (2) 69 Hình 16: Cây 70 Hình 17: Mức nút 71 Hình 18: Cây biểu diễn biểu thức 71 Hình 19: Các dạng nhị phân suy biến 72 Hình 20: Cây nhị phân hồn chỉnh nhị phân đầy đủ 72 Hình 21: Đánh số nút nhị phân đầy đủ để biểu diễn mảng 73 Hình 22: Nhược điểm phương pháp biểu diễn mảng .73 Hình 23: Cấu trúc nút nhị phân .74 Hình 24: Biểu diễn cấu trúc liên kết .74 Hình 25: Đánh số nút 3_phân để biểu diễn mảng 76 Hình 26: Biểu diễn tổng quát mảng 77 Hình 27: Cấu trúc nút tổng quát 78 Hình 28: Biểu thức dạng nhị phân 79 Hình 29: Vịng lặp QuickSort 94 Hình 30: Trạng thái trước gọi đệ quy 95 Hình 31: Heap 100 Hình 32: Vun đống 100 Hình 33: Đảo giá trị k[1] cho k[n] xét phần lại 101 Hình 34: Vun phần cịn lại thành đống lại đảo trị k[1] cho k[n-1] 101 Hình 35: Đánh số bit .104 Hình 36: Thuật tốn xếp trộn .109 Hình 37: Cài đặt thuật toán xếp với liệu lớn 121 vii Hình 38: Cây nhị phân tìm kiếm 126 Hình 39: Xóa nút BST 127 Hình 40 Xóa nút có nhánh BST 128 Hình 41: Xóa nút có hai nhánh BST thay nút cực phải trái 128 Hình 42: Xóa nút có hai nhánh BST thay nút cực trái phải 128 Hình 43: Đánh số bit 131 Hình 44: Cây tìm kiếm số học 131 Hình 45: Cây tìm kiếm số 134 Hình 46: Với độ dài dãy bit z = 3, tìm kiếm số gồm khoá 2, 4, sau thêm giá trị 135 Hình 47: RST chứa khoá 2, 4, 5, RST sau loại bỏ giá trị 136 Hình 48: Cây tìm kiếm số a) Trie tìm kiếm số b) 138 Hình 49: Hàm đệ quy tính số Fibonacci 149 Hình 50: Tính tốn truy vết 152 Hình 51: Truy vết 160 Hình 52: Ví dụ mơ hình đồ thị 176 Hình 53: Phân loại đồ thị 177 Hình 54 180 Hình 55 181 Hình 56: Đồ thị đường 184 Hình 57: Cây DFS 187 Hình 58: Cây BFS 190 Hình 59: Đồ thị G thành phần liên thơng G1, G2, G3 191 Hình 60: Khớp cầu 191 Hình 61: Liên thơng mạnh liên thơng yếu 192 Hình 62: Đồ thị đầy đủ 193 Hình 63: Đơn đồ thị vơ hướng bao đóng 193 Hình 64: Ba dạng cung ngồi DFS 197 Hình 65: Thuật tốn Tarjan "bẻ" DFS 199 Hình 66: Đánh số lại, đảo chiều cung duyệt BFS với cách chọn đỉnh xuất phát ngược lại với thứ tự duyệt xong (thứ tự 11, 10… 3, 2, 1) 204 Hình 67: Đồ thị G số ví dụ khung T1, T2, T3 208 Hình 68: Cây khung DFS (a) khung BFS (b) (Mũi tên chiều thăm đỉnh) 208 Hình 69: Phép định chiều DFS 211 Hình 70: Phép đánh số ghi nhận cung ngược lên cao 213 Hình 71: Mơ hình đồ thị toán bảy cầu 216 Hình 72 217 Hình 73 217 Hình 74 223 Hình 75: Phép đánh lại số theo thứ tự tôpô 238 Hình 76: Hai gốc r1 r2 hợp chúng 249 viii Hình 77: Mạng với khả thơng qua (1 phát, thu) luồng với giá trị 257 Hình 78: Mạng G mạng thặng dư Gf tương ứng (ký hiệu f[u,v]:c[u,v] luồng f[u, v] khả thông qua c[u, v] cung (u, v)) 261 Hình 79: Mạng thặng dư đường tăng luồng 262 Hình 80: Luồng mạng G trước sau tăng 262 Hình 81: Mạng giả mạng có nhiều điểm phát nhiều điểm thu 273 Hình 82: Thay đỉnh u hai đỉnh uin, uout 274 Hình 83: Mạng giả mạng có khả thông qua cung bị chặn hai phía 274 Hình 84: Đồ thị hai phía 280 Hình 85: Đồ thị hai phía ghép M .281 Hình 86: Mơ hình luồng tốn tìm ghép cực đại đồ thị hai phía 285 Hình 87: Phép xoay trọng số cạnh .289 Hình 88: Thuật tốn Hungari .292 Hình 89: Cây pha "mọc" lớn sau lần xoay trọng số cạnh tìm đường 299 Hình 90: Đồ thị G ghép M 304 Hình 91: Phép chập Blossom .306 Hình 92: Nở Blossom để dị đường xun qua Blossom .306 304 Chun đề §13 BÀI TỐN TÌM BỘ GHÉP CỰC ĐẠI TRÊN ĐỒ THỊ 13.1 CÁC KHÁI NIỆM Xét đồ thị G = (V, E), ghép đồ thị G tập cạnh đơi khơng có đỉnh chung Bài tốn tìm ghép cực đại đồ thị tổng quát phát biểu sau: Cho đồ thị G, phải tìm ghép cực đại G (bộ ghép có nhiều cạnh nhất) Với ghép M đồ thị G, ta gọi: Những cạnh thuộc M gọi cạnh ghép hay cạnh đậm Những cạnh không thuộc M gọi cạnh chưa ghép hay cạnh nhạt Những đỉnh đầu mút cạnh đậm gọi đỉnh ghép, đỉnh lại gọi đỉnh chưa ghép Một đường (đường khơng có đỉnh lặp lại) gọi đường pha bắt đầu cạnh nhạt cạnh đậm, nhạt nằm nối tiếp xen kẽ Một chu trình (chu trình khơng có đỉnh lặp lại) gọi Blossom qua đỉnh, bắt đầu kết thúc cạnh nhạt dọc chu trình, cạnh đậm, nhạt nằm nối tiếp xen kẽ Đỉnh xuất phát chu trình (cũng đỉnh kết thúc) gọi đỉnh sở (base) Blossom Đường mở đường pha bắt đầu đỉnh chưa ghép kết thúc đỉnh chưa ghép Ví dụ: Với đồ thị G ghép M Hình 90: Đường (8, 1, 2, 5, 6, 4) đường pha Chu trình (2, 3, 4, 6, 5, 2) Blossom Đường (8, 1, 2, 3, 4, 6, 5, 7) đường mở Đường (8, 1, 2, 3, 4, 6, 5, 2, 1, 9) có cạnh đậm/nhạt xen kẽ khơng phải đường pha (và tất nhiên đường mở) khơng phải đường Hình 90: Đồ thị G ghép M Ta dễ dàng suy tính chất sau: ĐHSPHN 1999-2004 Lý thuyết đồ thị 305 Đường mở Blossom đường độ dài lẻ với số cạnh nhạt nhiều số cạnh đậm cạnh Trong Blossom, đỉnh đỉnh sở đỉnh ghép đỉnh ghép với đỉnh phải thuộc Blossom Vì Blossom chu trình nên Blossom, đỉnh đỉnh sở tồn hai đường pha từ đỉnh sở đến nó, đường kết thúc cạnh đậm đường kết thúc cạnh nhạt, hai đường pha hình thành cách dọc theo chu trình theo hai hướng ngược Như ví dụ Hình 90, đỉnh có hai đường pha đỉnh sở tới: (2, 3, 4) đường pha kết thúc cạnh đậm (2, 5, 6, 4) đường pha kết thúc cạnh nhạt 13.2 THUẬT TOÁN EDMONDS (1965) Cơ sở thuật toán định lý (C.Berge): Một ghép M đồ thị G cực đại khơng tồn đường mở M Thuật tốn Edmonds: M := ∅; for (∀ đỉnh u chưa ghép) if 〈Tìm đường mở xuất phát từ u〉 then 〈Dọc đường mở: Loại bỏ cạnh đậm khỏi M; Thêm vào M cạnh nhạt〉; 〈Trả M ghép cực đại G〉; Điều khó thuật toán Edmonds phải xây dựng thuật toán tìm đường mở xuất phát từ đỉnh chưa ghép Thuật tốn xây dựng cách kết hợp thuật tốn tìm kiếm đồ thị với phép chập Blossom Xét đường pha xuất phát từ đỉnh x chưa ghép Những đỉnh đến từ x đường pha kết thúc cạnh nhạt gán nhãn "nhạt", đỉnh đến từ x đường pha kết thúc cạnh đậm gán nhãn "đậm" Với Blossom, ta định nghĩa phép chập (shrink) phép thay đỉnh Blossom đỉnh Những cạnh nối đỉnh thuộc Blossom tới đỉnh v khơng thuộc Blossom thay cạnh nối đỉnh chập với v giữ nguyên tính đậm/nhạt Dễ thấy sau phép chập, cạnh đậm đảm bảo ghép đồ thị mới: Lê Minh Hoàng 306 Chuyên đề Shrink Shrink Blossom Blossom = đỉnh sở blossom = đỉnh chập từ blossom Hình 91: Phép chập Blossom Thuật tốn tìm đường mở xuất phát từ đỉnh x phát biểu sau Trước hết đỉnh xuất phát x gán nhãn đậm Tiếp theo thuật toán tìm kiếm đồ thị x, theo nguyên tắc: từ đỉnh đậm phép cạnh nhạt từ đỉnh nhạt cạnh đậm Mỗi thăm tới đỉnh, ta gán nhãn đậm/nhạt cho đỉnh tiếp tục thao tác tìm kiếm đồ thị bình thường Cũng trình tìm kiếm, phát thấy cạnh nhạt nối hai đỉnh đậm, ta dừng lại gán nhãn tiếp gặp tình trạng đỉnh có hai nhãn đậm/nhạt, trường hợp này, Blossom phát (xem tính chất Blossom) bị chập thành đỉnh, thuật toán bắt đầu lại với đồ thị trả lời câu hỏi: "có tồn đường mở xuất phát từ x hay khơng?" Nếu đường mở tìm khơng qua đỉnh chập ta việc tăng cặp dọc theo đường mở Nếu đường mở có qua đỉnh chập ta lại nở đỉnh chập thành Blossom để thay đỉnh chập đường mở đoạn đường xuyên qua Blossom: Expand Expand Hình 92: Nở Blossom để dị đường xuyên qua Blossom ĐHSPHN 1999-2004 Lý thuyết đồ thị 307 Lưu ý Blossom bị chập, Blossom ảnh hưởng tới trình tìm đường mở phải chập để đảm bảo đường mở tìm đường Tuy nhiên việc cài đặt trực tiếp phép chập Blossom nở đỉnh rắc rối, địi hỏi chương trình với độ phức tạp O(n4) Dưới ta trình bày phương pháp cài đặt hiệu với độ phức tạp O(n3), phương pháp cài đặt không phức tạp, yêu cầu phải hiểu rõ chất thuật tốn 13.3 THUẬT TỐN LAWLER (1973) Trong thuật tốn Edmonds, sau chập Blossom thành đỉnh đỉnh hồn tồn lại nằm Blossom bị chập tiếp Thuật toán Lawler quan tâm đến đỉnh chập cuối cùng, đại diện cho Blossom (Outermost Blossom), đỉnh chập cuối định danh (đánh số) đỉnh sở Blossom ngồi Cũng thao tác chập/nở nói mà ta cần mở rộng khái niệm Blossom, coi Blossom tập đỉnh nở từ đỉnh chập không đơn chu trình pha Xét Blossom B có đỉnh sở đỉnh r Với ∀v∈B, v ≠ r, ta lưu lại hai đường pha từ r tới v, đường kết thúc cạnh đậm đường kết thúc cạnh nhạt, có hai loại vết gãn cho đỉnh v (hai vết cập nhật trình tìm đường): S[v] đỉnh liền trước v đường pha kết thúc cạnh đậm, không tồn đường pha loại S[v] = T[v] đỉnh liền trước v đường pha kết thúc cạnh nhạt, khơng tồn đường pha loại T[v] = Bên cạnh hai nhãn S T, đỉnh v cịn có thêm: Nhãn b[v] đỉnh sở Blossom chứa v Hai đỉnh u v thuộc Blossom ⇔ b[u] = b[v] Nhãn match[v] đỉnh ghép với đỉnh v Nếu v chưa ghép match[v] = Khi thuật tốn tìm đường mở đỉnh x chưa ghép phát biểu sau: Bước 1: (Init) Hàng đợi Queue dùng để chứa đỉnh đậm chờ duyệt, ban đầu gồm đỉnh đậm x Với đỉnh u, khởi gán b[u] = u match[u] = với ∀u Gán S[x] ≠ Với ∀u≠x, gán S[u] = Với ∀v: gán T[v] = Bước 2: (BFS) Lặp lại bước sau hàng đợi rỗng: Với đỉnh đậm u lấy từ Queue, xét cạnh nhạt (u, v): Lê Minh Hoàng 308 Chuyên đề Nếu v chưa thăm: Nếu: v đỉnh chưa ghép ⇒ Tìm thấy đường mở kết thúc v, dừng v đỉnh ghép ⇒ thăm v ⇒ thăm match[v] đẩy match[v] vào Queue Lưu vết: Cập nhật hai nhãn S T Nếu v thăm Nếu v đỉnh nhạt b[v] = b[u] ⇒ bỏ qua Nếu v đỉnh đậm b[v] ≠ b[u] ta phát blossom chứa u v, đó: Phát đỉnh sở: Truy vết đường ngược từ hai đỉnh đậm u v theo hai đường pha nút gốc, chọn lấy đỉnh a đỉnh đậm chung gặp q trình truy vết ngược Khi Blossom phát có đỉnh sở a Gán lại vết: Gọi (a = i[1], i[2], …, i[p] = u) (a = j[1], j[2], …, j[q] = v) hai đường pha dẫn từ a tới u v Khi (a = i[1], i[2], …, i[p] = u, j[q] = v, j[q1], …, j[1] = a) chu trình pha từ a tới u v quay trở a Bằng cách dọc theo chu trình theo hai hướng ngược nhau, ta gán lại tất nhãn S T đỉnh chu trình Lưu ý không gán lại nhãn S T cho đỉnh k mà b[k] = a, với đỉnh k có b[k] ≠ a bắt buộc phải gán lại nhãn S T theo chu trình S[k] T[k] trước có hay chưa Chập Blossom: Xét đỉnh v mà b[v]∈{b[i[1]], b[i[2]], …, b[i[p]], b[j[1]], b[j[2]], …, b[j[q]]}, gán lại b[v] = a Nếu v đỉnh đậm (có nhãn S[v] ≠ 0) mà chưa duyệt tới (chưa đẩy vào Queue) đẩy v vào Queue chờ duyệt tiếp bước sau Bước 3: Nếu bước tìm đường mở trả đường mở, bước khơng tìm thấy đường mở hàng đợi rỗng kết luận khơng tìm thấy đường mở Sau số ví dụ trường hợp từ đỉnh đậm u xét cạnh nhạt (u, v): Trường hợp 1: v chưa thăm chưa ghép: S:2 u x S:2 T:3 u v x v T:1 T:1 ⇒ Tìm thấy đường mở Trường hợp 2: v chưa thăm ghép ĐHSPHN 1999-2004 Lý thuyết đồ thị 309 S:2 S:2 T:3 S:4 v u x v u x T:1 T:1 ⇒ Thăm v lẫn match[v], gán nhãn T[v] S[match[v]] Trường hợp 3: v thăm, đỉnh đậm thuộc blossom với u T:3 S:5 T:7 S:4 u x T:1 S:2 T:3 S:7 v T:5 S:6 b[.] = ⇒ Không xét, bỏ qua Trường hợp 4: v thăm, đỉnh đậm b[u] ≠ b[v] T:3 S:4 T:3 S:5 T:7 S:4 a x T:1 S:2 x T:3 S:6 T:1 S:2 T:3 S:7 T:5 S:6 ⇒ Phát Blossom, tìm đỉnh sở a = 3, gán lại nhãn S T dọc chu trình pha Đẩy hai đỉnh đậm 4, vào hàng đợi, Tại bước sau, duyệt tới đỉnh 6, tìm thấy đường mở kết thúc 8, truy vết theo nhãn S T tìm đường (1, 2, 3, 4, 5, 7, 6, 8) Tư tưởng phương pháp Lawler dùng nhãn b[v] thay cho thao tác chập trực tiếp Blossom, dùng nhãn S T để truy vết tìm đường mở, tránh thao tác nở Blossom Phương pháp dựa nhận xét: Mỗi tìm đường mở, đường mở xuyên qua Blossom ngồi chắn phải vào Blossom từ nút sở thoát khỏi Blossom cạnh nhạt 13.4 CÀI ĐẶT Ta cài đặt phương pháp Lawler với khuôn dạng Input/Output sau: Input: file văn GMATCH.INP Lê Minh Hoàng 310 Chuyên đề Dòng 1: Chứa hai số n, m số cạnh số đỉnh đồ thị cách dấu cách (n ≤ 100) m dòng tiếp theo, dòng chứa hai số u, v tượng trưng cho cạnh (u, v) đồ thị Output: file văn GMATCH.OUT, ghi ghép cực đại tìm 10 GMATCH.INP 10 11 12 16 24 28 34 36 56 59 10 78 79 GMATCH.OUT 1) 2) 3) 4) 10 5) Chương trình sửa đổi chút mơ hình cài đặt dựa vào nhận xét: v đỉnh đậm ⇔ v = x match[v] đỉnh nhạt Nếu v đỉnh đậm S[v] = match[v] Vậy ta khơng cần phải sử dụng riêng mảng nhãn S[v], bước sửa vết, ta cần sửa nhãn vết T[v] mà thơi Để kiểm tra đỉnh v ≠ x có phải đỉnh đậm hay khơng, ta kiểm tra điều kiện: match[v] có đỉnh nhạt hay khơng, hay T[match[v]] có khác hay khơng Chương trình sử dụng biến với vai trò sau: match[v] đỉnh ghép với đỉnh v b[v] đỉnh sở Blossom chứa v T[v] đỉnh liền trước v đường pha từ đỉnh xuất phát tới v kết thúc cạnh nhạt, T[v] = trình BFS chưa xét tới đỉnh nhạt v InQueue[v] biến Boolean, InQueue[v] = True ⇔ v đỉnh đậm đẩy vào Queue để chờ duyệt start finish: Nơi bắt đầu kết thúc đường mở P_4_13_1.PAS * Phương pháp Lawler áp dụng cho thuật toán Edmonds program MatchingInGeneralGraph; const InputFile = 'GMATCH.INP'; OutputFile = 'GMATCH.OUT'; max = 100; var a: array[1 max, max] of Boolean; match, Queue, b, T: array[1 max] of Integer; InQueue: array[1 max] of Boolean; n, Front, Rear, start, finish: Integer; procedure Enter; var i, m, u, v: Integer; ĐHSPHN 1999-2004 Lý thuyết đồ thị f: Text; begin Assign(f, InputFile); Reset(f); FillChar(a, SizeOf(a), False); ReadLn(f, n, m); for i := to m begin ReadLn(f, u, v); a[u, v] := True; a[v, u] := True; end; Close(f); end; procedure Init; {Khởi tạo ghép rỗng} begin FillChar(match, SizeOf(match), 0); end; procedure InitBFS; {Thủ tục gọi để khởi tạo trước tìm đường mở xuất phát từ start} var i: Integer; begin {Hàng đợi gồm đỉnh đậm start} Front := 1; Rear := 1; Queue[1] := start; FillChar(InQueue, SizeOf(InQueue), False); InQueue[start] := True; {Các nhãn T khởi gán = 0} FillChar(T, SizeOF(T), 0); {Nút sở outermost blossom chứa i i} for i := to n b[i] := i; finish := 0; {finish = nghĩa chưa tìm thấy đường mở} end; procedure Push(v: Integer); {Đẩy đỉnh đậm v vào hàng đơi} begin Inc(Rear); Queue[Rear] := v; InQueue[v] := True; end; function Pop: Integer; {Lấy đỉnh đậm khỏi hàng đợi, trả kết hàm} begin Pop := Queue[Front]; Inc(Front); end; {Khó phương pháp Lawler thủ tục này: Thủ tục xử lý gặp cạnh nhạt nối hai đỉnh đậm p, q} procedure BlossomShrink(p, q: Integer); var i, NewBase: Integer; Mark: array[1 max] of Boolean; {Thủ tục tìm nút sở cách truy vết ngược theo đường pha từ p q} function FindCommonAncestor(p, q: Integer): Integer; var InPath: array[1 max] of Boolean; begin FillChar(InPath, SizeOf(Inpath), False); repeat {Truy vết từ p} p := b[p]; {Nhảy tới nút sở Blossom chứa p, phép nhảy để tăng tốc độ truy vết} InPath[p] := True; {Đánh dấu nút đó} Lê Minh Hồng 311 312 Chuyên đề if p = start then Break; {Nếu truy đến nơi xuất phát dừng} p := T[match[p]]; {Nếu chưa đến start truy lùi tiếp hai bước, theo cạnh đậm theo cạnh nhạt} until False; repeat {Truy vết từ q, tương tự p} q := b[q]; if InPath[q] then Break; {Tuy nhiên chạm vào đường pha p dừng ngay} q := T[match[q]]; until False; FindCommonAncestor := q; {Ghi nhận đỉnh sở mới} end; procedure ResetTrace(x: Integer); {Gán lại nhãn vết dọc đường pha từ start tới x} var u, v: Integer; begin v := x; while b[v] NewBase {Truy vết đường pha từ start tới đỉnh đậm x} begin u := match[v]; Mark[b[v]] := True; {Đánh dấu nhãn blossom đỉnh đường đi} Mark[b[u]] := True; v := T[u]; if b[v] NewBase then T[v] := u; {Chỉ đặt lại vết T[v] b[v] nút sở mới} end; end; begin {BlossomShrink} FillChar(Mark, SizeOf(Mark), False); {Tất nhãn b[v] chưa bị đánh dấu} NewBase := FindCommonAncestor(p, q); {xác định nút sở} {Gán lại nhãn} ResetTrace(p); ResetTrace(q); if b[p] NewBase then T[p] := q; if b[q] NewBase then T[q] := p; {Chập blossom ⇔ gán lại nhãn b[i] blossom b[i] bị đánh dấu} for i := to n if Mark[b[i]] then b[i] := NewBase; {Xét đỉnh đậm i chưa đưa vào Queue nằm Blossom mới, đẩy i Queue để chờ duyệt sau} for i := to n if not InQueue[i] and (b[i] = NewBase) then Push(i); end; {Thủ tục tìm đường mở} procedure FindAugmentingPath; var u, v: Integer; begin InitBFS; {Khởi tạo} repeat {BFS} u := Pop; {Xét đỉnh v chưa duyệt, kề với u, không nằm Blossom với u} for v := to n if (T[v] = 0) and (a[u, v]) and (b[u] b[v]) then {dĩ nhiên T[v] = (u, v) cạnh nhạt rồi} begin if match[v] = then {Nếu v chưa ghép ghi nhận đỉnh kết thúc đường mở thoát ngay} begin T[v] := u; finish := v; Exit; end; {Nếu v đỉnh đậm gán lại vết, chập Blossom …} if (v = start) or (T[match[v]] 0) then BlossomShrink(u, v) ĐHSPHN 1999-2004 Lý thuyết đồ thị 313 else {Nếu không ghi vết đường đi, thăm v, thăm ln match[v] đẩy tiếp match[v] vào Queue} begin T[v] := u; Push(match[v]); end; end; until Front > Rear; end; procedure Enlarge; {Nới rộng ghép đường mở start, kết thúc finish} var v, next: Integer; begin repeat v := T[finish]; next := match[v]; match[v] := finish; match[finish] := v; finish := next; until finish = 0; end; procedure Solve; {Thuật toán Edmonds} var u: Integer; begin for u := to n if match[u] = then begin start := u; {Với đỉnh chưa ghép start} FindAugmentingPath; {Tìm đường mở start} if finish then Enlarge; {Nếu thấy nới rộng ghép theo đường mở này} end; end; procedure Result; {In ghép tìm được} var u, count: Integer; f: Text; begin Assign(f, OutputFile); Rewrite(f); count := 0; for u := to n if match[u] > u then {Vừa tránh trùng lặp (u, v) (v, u), vừa loại đỉnh không ghép (match=0)} begin Inc(count); WriteLn(f, count, ') ', u, ' ', match[u]); end; Close(f); end; begin Enter; Init; Solve; Result; end 13.5 ĐỘ PHỨC TẠP TÍNH TỐN Thủ tục BlossomShrink có độ phức tạp O(n) Thủ tục FindAugmentingPath cần không n lần gọi thủ tục BlossomShrink, cộng thêm chi phí thuật tốn tìm kiếm theo chiều rộng, có Lê Minh Hoàng 314 Chuyên đề độ phức tạp O(n2) Phương pháp Lawler cần không n lần gọi thủ tục FindAugmentingPath nên có độ phức tạp tính tốn O(n3) Cho đến nay, phương pháp tốt để giải toán tìm ghép tổng quát đồ thị biết đến Micali Vazizani (1980), có độ phức tạp tính tốn O( n.m) Bạn tham khảo tài liệu khác ĐHSPHN 1999-2004 TÀI LIỆU ĐỌC THÊM Dưới hai sách nói kinh điển mà hầu hết tài liệu thuật tốn trích dẫn nhiều từ hai sách Các bạn nên tìm cách để đọc Title: The Art of Computer Programming Author: Donald E Knuth Volume 1: Fundamental Algorithms Volume 2: Seminumerical Algorithms Volume 3: Sorting and Searching Volume 4: Combinatorial Algorithms (in preparation) Volume 5: Syntactic Algorithms (in preparation) Title: Introduction to Algorithms Authors: Thomas H.Cormen, Charles E.Leiserson, Ronald L.Rivest