1. Trang chủ
  2. » Giáo Dục - Đào Tạo

bồi dưỡng học sinh giỏi môn tin học thpt chuyên đề cây KHUNG và cây KHUNG NHỎ NHẤT

17 324 0

Đ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

Thông tin cơ bản

Định dạng
Số trang 17
Dung lượng 333,7 KB

Nội dung

CÂY KHUNG CÂY KHUNG NHỎ NHẤT Đặt vấn đề Hệ thống đường giao thông thành phố biểu thị đơn đồ thị cho hình 1a Các để đường lại vào mùa đông phải cào tuyết thường xuyên Chính quyền địa phương muốn cáo tuyết số đường cho có đường thông suốt nối hai thành phố Có thể làm điều cách nào? a a b c e d f b c e d f (a) (b) Hình a) Hệ thống đường b) tập đường cần phải cào tuyết Cần phải cào tuyết năm đường đảm bảo có đường hai thành phố Hình 1b biểu thị tập hợp đường Ta nhận thấy đồ thị biểu diễn đường liên thông chứa sáu đỉnh, năm cạnh Bài toán giải đồ thị có số tối thiểu cạnh chứa tất đỉnh đồ thị xuất phát Đồ thị phải Cây khung 2.1 Định nghĩa Cho G đơn đồ thị Một gọi khung G đồ thị G chứa tất đỉnh G Một đơn đồ thị có khung đồ thị liên thông có đường khung hai đỉnh Điều ngược lại đúng, tức đồ thị liên thông có khung 2.2 Định lí Một đơn đồ thị liên thông có khung Chứng minh: Trước tiên, giả sử đồ thị G có khung T T chứa tất đỉnh G Hơn nữa, có đường T hai đỉnh Vì T đồ thị G nên có đường G hai đỉnh Do G liên thông Bây giờ, giả sử G liên thông Nếu G phải có chu trình đơn Xóa cạnh chu trình đơn Đồ thị nhận số cạnh chứa tất đỉnh G liên thông Nếu đồ thị không chứa chu trình đơn Cũng giống trên, ta lại xóa cạnh chu trình đơn Lặp lại trình không chu trình đơn Điều có số hữu hạn cạnh đồ thị Quá trình kết thúc không chu trình đơn đồ thị nhận Cây tạo đồ thị liên thông xóa cạnh Cây khung chứa tất đỉnh G 2.3 Tìm kiếm ưu tiên theo chiều sâu Cách chứng minh định lí đưa thuật toán tìm khung cách xóa cạnh khỏi chu trình đơn Thuật toán không hiệu đòi hỏi phải nhận biết chu trình đơn Thay cho việc xây dựng khung cách loại bỏ cạnh, khung xây dựng cách ghép thêm cạnh Ta xây dựng khung đồ liên thông phương pháp tìm kiếm ưu tiên theo chiều sâu Nghĩa tạo có gốc khung đồ thị vô hướng có gốc Chọn tùy ý đỉnh đồ thị làm gốc Xây dựng đường từ đỉnh cách ghép thêm cạnh vào cho mạnh ghép nối đỉnh cuối đường với đỉnh chưa thuộc đường Tiếp tục ghép thêm cạnh vào đường chừng thêm Nếu đường qua tất đỉnh đồ thị đường tạo nên khung Nhưng đường không qua tất đỉnh cần thêm cạnh khác vào đường Lùi lại đỉnh trước đỉnh cuối đường có thể, xây dựng đường xuất phát từ đỉnh qua đỉnh chưa thuộc đường Nếu điều làm lùi thêm đỉnh đường đi, tức lùi lại hai đỉnh đường thử xây dựng đường Lặp lại thủ tục này, đỉnh cuối ghé thăm lùi theo đường lần đỉnh, xây dựng đường dài tốt thêm cạnh Vì đồ thị có hữu hạn cạnh liên thông nên trình kết thúc tạo khung Mỗi đỉnh mà đường kết thúc giai đoạn thuật toán có gốc Mỗi đỉnh đường đỉnh Tìm kiếm ưu tiên chiều sâu gọi thủ tục quay lui quay lại đỉnh ghé thăm trước đường Các cạnh đồ thị tìm nhờ tím kiếm ưu tiên theo chiều sâu gọi cạnh Các cạnh khác đồ thị nối với đỉnh trước sau Các cạnh gọi cạnh quay lui 2.4 Thuật toán tìm kiếm ưu tiên theo chiều sâu Trong thuật toán này, xây dựng khung đồ thị G với đỉnh v1, v2, …, cách lấy đỉnh v1 làm gốc Khởi tạo tập T có đỉnh Trong bước, thêm đỉnh vào T với cạnh từ đỉnh T không chứa chu trình cạnh thêm vào mà nối với đỉnh có Tuy nhiên, T liên thông xây dựng Vì G liên thông, đỉnh G thăm ghép vào Từ suy T khung G procedure DFS(G: đồ thị liên thông với đỉnh v1, v2, …, vn) T:= chứa đỉnh v1 visit(v1) procedure visit(v: đỉnh G) for đỉnh w liền kề với v chưa có T Begin thêm đỉnh w cạnh (v, w) vào T visit(w) end Phân tích độ phức tạp: Với đỉnh v thủ tục visit(v) gọi đỉnh v lần gặp tìm kiếm không gọi lại Giả sử ta có danh sách kề G, để tìm đỉnh kề v không cần phải tính toán Theo bước thuật toán xem xét cạnh nhiều hai lần để định xem có nên thêm cạnh vào đỉnh cuối hay không Do thủ tục DFS xây dựng khung dùng O(e) hay O(n2) bước e n tương ứng số cạnh, số đỉnh G 2.5 Tìm kiếm ưu tiên chiều rộng Có thể xây dựng khung đơn đồ thị thuật toán tìm kiếm ưu tiên theo chiều rộng Một lần nữa, có gốc xây dựng đồ thị vô hướng có gốc tạo nên khung Chọn đỉnh đồ thị làm gốc Sau ghép vào tất cạnh liên thuộc với đỉnh Các đỉnh ghép vào giai đoạn trở thành đỉnh mức khung Sắp xếp chúng theo thứ tự tùy ý Tiếp theo với đỉnh mức ghé thăm theo thứ tự xếp ta ghép tất cạnh liên thuộc với vào mà không tạo chu trình Sắp xếp đỉnh đỉnh mức theo trật tự Quá trình tạo đỉnh mức Tiếp tục làm lại thủ tục tất đỉnh đồ thị ghép vào Thủ tục kết thúc có số hữu hạn cạnh đồ thị Cây khung tạo xây dựng chứa tất đỉnh đồ thị 2.6 Thuật toán tìm kiếm ưu tiên theo chiều rộng Trong thuật toán giả sử đỉnh v1, v2, …, đồ thị liên thông G xếp theo thứ tự Chúng ta dùng từ xử lí để mô tả thủ tục thêm đỉnh cạnh vào kề với đỉnh thời xử lí để không tạo vòng lặp procedure BFS(G: đồ thị liên thông với đỉnh v1, v2, …, vn) T:= chứa đỉnh v1 L:= danh sách rỗng Đặt v1 vào danh sách L gồm đỉnh không xử lí While L khác rỗng Begin Xóa đỉnh đầu tiên, v1 khỏi L For đỉnh kề w v If w chưa nằm L không thuộc T then Begin Thêm đỉnh w vào cuối danh sách L Thêm đỉnh w cạnh {v, w} vào T end end Phân tích độ phức tạp: Với đỉnh v đồ thị xem xét tất đỉnh liền kề với v thêm vào T đỉnh chưa thăm Giả sử có danh sách đỉnh kề đồ thị Khi dễ dàng xác định xem đỉnh liền kề với đỉnh cho, xét cạnh nhiều hai lần để xem có thêm cạnh hay không đỉnh cuối nằm hay chưa Từ suy thuật toán tìm kiếm ưu tiên chiều rộng dùng O(e) O(n2) bước 2.7 Tìm kiếm ưu tiên chiều rộng đồ thị có hướng Chúng ta dễ dàng thay đổi tìm kiếm ưu tiên chiều sâu tìm kiếm ưu tiên chiều rộng để chúng chạy đầu vào đồ thị có hướng Tuy nhiên, thông tin không thiết khung mà có lẽ rừng khung Trong hai thuật toán thêm cạnh mà có hướng từ đỉnh thăm tới đỉnh chưa thêm vào Nếu giai đoạn thuật toán mà cạnh đỉnh thêm vào tới đỉnh chưa thêm vào cạnh đưa vào thuật toán trở thành gốc rừng khung Ví dụ: Cho đồ thị có hướng G Hãy xác định rừng khung thuật toán tìm kiếm ưu tiên chiều sâu Chúng ta bắt đầu tìm kiếm ưu tiên chiều sâu đỉnh a thêm đỉnh b, c g cạnh tương ứng, đến g f e h không tiếp Khi cần quay lại c bị tắc quay lui tới b Tại chọn đỉnh f e cạnh tương ứng Việc quay lui tiếp đưa ta a Khi xây d j i k l thêm đỉnh h, l, k, j cạnh tương ứng Khi không tiếp nữa, quay lui k, sau l, h, d Cuối lại xây i kết thúc tìm kiếm a b c dGiải: Cây khung nhỏ Một lớp rộng toán giải cách tìm khung nhỏ đồ thị có trọng số cho tổng trọng số cạnh nhỏ Định nhĩa: Cây khung nhỏ đồ thị liên thông có trọng số khung có tổng trọng số cạnh nhỏ 2.9 Thuật toán tìm khung nhỏ Sau trình bày hai thuật toán tìm khung nhỏ Cả hai tiến hành cách ghép cạnh có trọng số nhỏ số cạnh có tính chất mà chưa dùng Những thuật toán ví dụ thuật toán tham lam Thuật toán tham lam thủ tục thực lựa chọn tối ưu giai đoạn Tối ưu hóa giai đoạn thuật toán không đảm bảo tạo lời giải tối ưu toàn cục, hai thuật toán sau để xây dựng khung nhỏ thuật toán tham lam tạo lời giải tối ưu Thuật toán Robert Prim đưa năm 1957 Để thực thuật toán ta bắt đầu việc chọn cạnh có trọng số nhỏ nhất, đặt vào khung Lần lượt ghép vào cạnh có trọng số tối thiểu liên thuộc với đỉnh không tạo chu trình Thuật toán dừng (n-1) cạnh ghép vào procedure PRIM(G: đồ thị liên thông có trọng số với n đỉnh) T:= cạnh có trọng số nhỏ For i:=1 to n-2 Begin E:= cạnh có trọng số tối thiểu liên thuộc với đỉnh T không tạo chu trình T ghép vào T T:=T với e ghép vào End {T khung nhỏ nhất} Lưu ý: Việc chọn cạnh ghép vào giai đoạn thuật toán không xác định có nhiều cạnh trọng số thỏa mãn tiêu chuẩn Cần xếp cạnh theo thứ tự để việc chọn cạnh xác định Cũng cần ý có nhiều khung nhỏ ứng với đồ thị liên thông có trọng số Thuật toán thứ hai Joeseph Kruskal phát minh vào năm 1956 Để thực thuật toán chọn cạnh có trọng số nhỏ đồ thị Lần lượt ghép thêm vào cạnh có trọng số tối thiểu không tạo thành chu trình với cạnh chọn Thuật toán dừng sau (n-1) cạnh chọn procedure KRUSKAL(G: đồ thị n đỉnh, liên thông, có trọng số) T:= đồ thị rỗng For i:=1 to n-1 Begin E:=một cạnh G với trọng số nhỏ không tạo chu trình T, ghép vào T T:=T với cạnh e ghép thêm vào End {T khung nhỏ nhất} Sự khác hai thuật toán: Trong PRIM chọn cạnh có trọng số tối thiểu liên thuộc với đỉnh thuộc không tạo chu trình KRUKAL chọn cạnh có trọng số tối thiểu mà không thiết phải liên thuộc với đỉnh không tạo chu trình a c b 2.10 Bài tập ứng dụng: d Bài Cho đồ thị hình bên phải, tìm khung e g f Giải: Đồ thị G liên thông, chứa chu trình đơn Xóa cạnh {a, e} loại chu trình, đồ thị nhận liên thông chứa tất đỉnh G Tiếp theo xóa cạnh {e, f} loại chu trình nữa, cuối xóa cạnh {c, g} sinh đồ thị chu trình Đồ thị khung chứa tất đỉnh G Đáp án cho hình đây: Các khung G cho hình đây: a c b e d a g d e g f a c b f c {a, e}b e d a c {e, f} b e g d g f f Bài Dùng thuật toán tìm kiếm ưu tiên chiều sâu, tìm khung đồ {c, g} thị G cho hình bên j d i Giải: Xuất phát từ đỉnh a tùy ý, ví dụ đỉnh f Đường xây f e dựng cách ghép c nhiều tốt, cạnh liên thuộcb h k với đỉnh chưa thuộc đường đi, g điều tạo đường f, g, h, k j Tiếp theo, lùi lại k Không đường k chứa đỉnh chưa ghé thăm Vì lùi lại tới h, từ h có đường h, i Sau lùi h tiếp tục lùi f Từ f có đường f, d, e, c, a Ta lại lùi c xây dựng đường c, b Thủ tục xây dựng xong khung f f g g h h k g i j (a) (b) g d h e h k j f f i a j (c) e i c k c k d b j (d) a Bài Dùng thuật toán tìm kiếm ưu tiên chiều c b l a rộng, tìm khung đồ thị G cho hình bên Giải: Chọn đỉnh e làm gốc cây, sau e f gkề thêm cạnh liên thuộc vào tất đỉnh lền d với e, tức cạnh từ e tới b, d, f i ghép vào Vậy mức có đỉnh Tiếp i h theo, ghép cạnh từ đỉnh mức nối với j đỉnh chưa có Vì cạnh từ b tới a c ghép vào, thế, cạnh từ d tới k m h, từ f tới j g từ i tới k Các đỉnh a, c, h, g, j, k mức Tiếp theo, ghép cạnh từ đỉnh nối với đỉnh chưa thuộc vào cây, tức ghép thêm cạnh từ g tới l từ k tới m e e b d i f e b e d a c g h b i f j d a k c i f g h j k l m Bài Dùng thuật toán PRIM, tìm khung nhỏ đồ thị cho hình Giải: Cây khung nhỏ xây dựng thuật toán PRIM thể hình dưới, bên phải a 3 j h k g f h i d e l c 1 b g a f e d c b i 3 j k l Bài Dùng thuật toán KRUSKAL, tìm khung nhỏ đồ thị cho hình Giải: Cây khung nhỏ xây dựng thuật toán KRUSKAL thể hình dưới, bên phải a 3 j i h l g f d e k c b h a g f d e c b i 3 j k l PHỤ LỤC: MỘT SỐ CHƯƠNG TRÌNH MẪU THAM KHẢO KRUSCAL: #include #include #define SIZE 100 using namespace std; struct Edge { int beginVertex, endVertex, weight; }; Edge edges[SIZE*SIZE] = {{0,1,6},{0,2,5},{0,3,4},{1,3,8},{2,3,3},{2,4,2}, {3,4,1}}; int vertexNumber = 5; int edgeNumber = 7; Edge mst[SIZE*SIZE]; int mstNumber; int parent[SIZE]; bool compareEdge(const Edge& e1, const Edge& e2) { return (e1.weight < e2.weight); } int findSet(int u) { int v = u; while(parent[v] >= 0) v = parent[v]; return v; } void unionSet(int u,int v) { int x = findSet(u); int y = findSet(v); if (parent[x] > parent[y]){ parent[y] += parent[x]; parent[x] = y; } else { parent[x] += parent[y]; parent[y] = x; } } void kruskal() { int i, beginRoot, endRoot; for(i=0; i

Ngày đăng: 29/04/2017, 19:47

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w