HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG BÀI TẬP LỚN MÔN HỌC TOÁN RỜI RẠC NHÓM MÔN HỌC 02 Giảng viên Dương Thị Thanh Tú Sinh viên Nguyễn Khôi Nguyên Nguyễn Đức Lân Nguyễn Trung Đức Nguyễn Bá Phúc Nhóm[.]
HỌC VIỆN CƠNG NGHỆ BƯU CHÍNH VIỄN THƠNG BÀI TẬP LỚN MƠN HỌC: TỐN RỜI RẠC NHĨM MƠN HỌC: 02 Giảng viên: Dương Thị Thanh Tú Sinh viên: Nguyễn Khôi Nguyên Nguyễn Đức Lân Nguyễn Trung Đức Nguyễn Bá Phúc Nhóm Bài tập lớn : 1_5 Hà Nội năm 2022 Chương I Giới thiệu mục đích đề tài .4 Giới thiệu đề tài a Chu trình Euler(đồ thị Euler): b Chu trình Hamilton(đồ thị Hamilton): Chương II Kiến thức sở .5 Đồ thị Euler .5 Thuật toán tìm chu trình Euler .5 2.1 Chứng minh đồ thị Euler 2.2 Biểu diễn thuật tốn tìm chu trình Euler .6 Đồ thị Hamilton Thuật tốn tìm tất chu trình Hamilton 4.1 Chứng minh chu trình Hamilton 4.2 Biểu diễn thuật tốn tìm chu trình Hamilton Chương III Ứng dụng .8 A Bài toán Người đưa thư I - Phát biểu toán người đưa thư Phát biểu toán: Cách giải: II – Phương pháp giải kiểm nghiệm .9 Phương pháp giải: Kiểm nghiệm: .9 III –Chương trình .10 Bài toán người đưa thư .10 Cài đặt thuật toán 11 B Bài toán Người du lịch 16 I - Phát biểu toán người du lịch .16 Phát biểu toán: 16 Cách giải: 16 II – Chương trình 16 Bài toán người du lịch 16 2.Cài đặt thuật toán 17 Chương I Giới thiệu mục đích đề tài Giới thiệu đề tài a Chu trình Euler(đồ thị Euler): Là khái niệm xuất phát từ toán cầu Euler giải vào khoảng năm 1737 Người dân thành phố đặt câu hỏi thử tìm cách xuất phát từ vùng đi, qua tất cầu, qua lần trở nơi xuất phát Nhà toán học Euler mơ tả mơ hình tốn đồ thị vô hướng với đỉnh ứng với vùng, cạnh ứng với cầu Euler chứng minh tốn khơng có lời giải Ơng chứng minh chu trình có dạng mong muốn tồn khơng có nút bậc lẻ Một đường gọi chu trình Euler b Chu trình Hamilton(đồ thị Hamilton): Khái niệm đường chu trình Hamilton đưa William Rowan Hamilton vào năm 1856, sau thiết kế trị chơi khối đa diện 20 đỉnh, 30 cạnh, 12 mặt, mặt ngũ giác người chơi cần chọn cạnh để thành lập đường qua đỉnh cho trước(cịn gọi trị chơi Icosian) Bài tốn tổng quát Hamilton đưa là: Tìm chu trình đơn qua tất đỉnh đồ thị, đỉnh lần sau quay trở điểm xuất phát Cho đến nay, toán chưa có lời giải trường hợp đồ thị tổng quát Những toán liên quan tới chu trình Hamilton tốn NP-hard Mọi thuật tốn tìm kiếm chu trình Hamilton thiết kế dựa mơ hình duyệt mà thơi Mục đích: Giúp người có thêm kiến thức lý thuyết đô thị hiểu đồ thị Euler Hamilton Giúp giải toán ứng dụng Chương II Kiến thức sở Đồ thị Euler Định nghĩa: - Chu trình đơn đồ thị G qua cạnh đồ thị lần gọi chu trình Euler - Đồ thị gọi đồ thị Euler có chu trình Euler Thuật tốn tìm chu trình Euler Để tìm chu trình Euler đồ thị ta sử dụng kết định lý sau Định lý Điều kiện cần đủ để đồ thị G= Euler Đồ thị vô hướng liên thông G= đồ thị Euler đỉnh G có bậc chẵn Đồ thị có hướng liên thông yếu G= đồ thị Euler tất đỉnh có bán đỉnh bậc bán đỉnh bậc vào (điều làm cho đồ thị liên thông mạnh) 2.1 Chứng minh đồ thị Euler Đối với đồ thị vơ hướng, để chứng minh đồ thi có Euler hay khơng ta cần thực hiện: • Kiểm tra đồ thị có liên thơng hay khơng? Điều dễ dàng thực cách kiểm tra DFS(u) = V BFS(u) = V ta kết luận đồ thị liên thông (u đỉnh đồ thị) • Sử dụng tính chất ma trận kề biểu đồ thị vơ hướng để tính tốn bậc đỉnh Đối với đồ thị có hướng, để chứng minh đồ thi có Euler hay khơng ta cần thực hiện: • Kiểm tra đồ thị có liên thông yếu hay không? Điều dễ dàng thực cách kiểm tra tồn đỉnh u V để DFS(u) = V BFS(u) = V ta kết luận đồ thị liên thơng yếu • Sử dụng tính chất ma trận kề biểu đồ thị có hướng để tính bán đỉnh bậc bán đỉnh bậc vào đỉnh Bán đỉnh bậc đỉnh u deg+(u) số số hàng u Bán đỉnh bậc vào đỉnh u deg-(u) số số cột u 2.2 Biểu diễn thuật tốn tìm chu trình Euler Thuật toán Euler-Cycle(u): Bước (Khởi tạo) : stack =; //Khởi tạo stack bắt đầu CE = ; //Khởi tạo mảng CE bắt đầu Push (stack, u) ; //Đưa đỉnh u vào ngăn xếp Bước (Lặp ): while (stack ) { //Lặp stack rỗng s = get(stack); //Lấy đỉnh đầu ngăn xếp if ( Ke(s) ) then { // Nếu danh sách Ke(s) chưa rỗng t =< Đỉnh Ke(s)>; Push(stack, t)‟ //Đưa t vào stack; E = E \ (s,t); // Loại bỏ cạnh (s,t); } else { //Trường hợp Ke(s)= s = Pop(stack);// Đưa s khỏi ngăn xếp s CE; //Đưa s sang CE } } Bước (Trả lại kết quả) : ; Đồ thị Hamilton - Chu trình bắt đầu đỉnh v qua tất đỉnh lại đỉnh lần sau quay trở lại v gọi chu trình Hamilton - Đồ thị có chu trình Hamilton gọi đồ thị Hamilton Thuật toán tìm tất chu trình Hamilton Một số quy luật tìm chu trình Hamilton: Cho đồ thị G=< V,E > • 1.Nếu đỉnh v có bậc < 2: Khơng có chu trình Hamilton • 2.Nếu đỉnh v có bậc = cạnh xuất chu trình Hamilton • 3.Khi chọn cạnh đỉnh, xóa tất cạnh cịn lại • 4.Nếu đỉnh v kề với > đỉnh bậc => Khơng có chu trình Hamilton 4.1 Chứng minh chu trình Hamilton Để tìm chu trình Hamilton đồ thị ta dựa vào định lý sau Định lý 1: Xét với đồ thị vơ hướng G, tồn k đỉnh cho xóa k đỉnh với cạnh liên thuộc chúng đồ thị nhận có nhiều k thành phần liên thơng Khi đó, khẳng định G khơng phải đồ thị Hamilton Định lý 2: (Dirak,1952): Xét đơn đồ thị vô hướng G = (V, E) có n đỉnh (n ≥ 3) Nếu đỉnh có bậc khơng nhỏ [n/2] G đồ thị Hamilton Định lý 3: (Ghouila – Houiri, 1960): Xét đơn đồ thị có hướng liên thơng mạnh G = (V, E) có n đỉnh Nếu phiên vơ hướng G, đỉnh có bậc khơng nhỏ n G đồ thị Hamilton Định lý 4: (Ore, 1960): Xét đơn đồ thị vơ hướng G = (V, E) có n đỉnh (n ≥3) Xét cặp đỉnh không kề nhau, cặp đỉnh tổng bậc nhỏ n G đồ thị Hamilton Định lý 5: (Meynie, 1973): Xét đơn đồ thị có hướng liên thơng mạnh G = (V, E) có n đỉnh Nếu phiên vô hướng G, cặp đỉnh không kề có tổng bậc khơng nhỏ 2n-1 G đồ thị Hamilton 4.2 Biểu diễn thuật tốn tìm chu trình Hamilton Thuật tốn liệt kê tất chu trình Hamilton bắt đầu đỉnh thứ k Hamilton(int k){ for(y ∈ Ke(X[k-1])){ if((k == n+1) && (y == v0)) Ghinhan(X[1],X[2],…,X[n], v0); else if(chuaxet[y] == true){ X[k] = y; chuaxet[y] = false; Hamilton(k+1); chuaxet[y] = true; } } } Khi đó, việc liên kết chu trình Hamilton thực sau: Hamilton-Cycle(v0){ //Khởi tạo đỉnh chưa xét for(v ∈ V) chuaxet[v] = true; X[1] = v0; //v0 đỉnh đồ thị chuaxet[v0] = false; //Đánh dấu v0 xét Hamilton(2); //Gọi thủ tục duyệt } Chương III Ứng dụng A Bài toán Người đưa thư I - Phát biểu toán người đưa thư Phát biểu toán: MỘT NGƯỜI ĐƯA THƯ XUẤT PHÁT TỪ BƯU ĐIỆN PHẢI ĐẾN MỘT SỐ CON ĐƯỜNG ĐỂ PHÁT THƯ RỒI QUAY TRỞ VỀ ĐIỂM XUẤT PHÁT, HỎI NGƯỜI ĐÓ PHẢI ĐI NHƯ THẾ NÀO ĐỂ SỐ ĐƯỜNG ĐI LÀ NGẮN NHẤT ? Cách giải: Ta xét toán dạng đơn giản sau : Cho đồ thị vô hướng, liên thơng có trọng số G Một chu trình qua cạnh G gọi hành trình G Trong hành trình đó, tìm hành trình ngắn Rõ ràng G đồ thị Euler (mọi đỉnh có bậc chẵn) chu trình Euler G (qua cạnh G lần ) hành trình ngắn cần tìm Chỉ cịn phải xét trường hợp G có số đỉnh bậc lẻ (số đỉnh bậc lẻ số chẵn) Khi đó, hành trình G qua lần số cạnh Dữ liệu đầu vào Biểu diễn đồ thị liên thông G ma trận kề có trọng số Với đỉnh khơng có cạnh nối giá trị II – Phương pháp giải kiểm nghiệm Phương pháp giải: ĐỒ THỊ LIÊN THƠNG G VƠ HƯỚNG CĨ TRỌNG SỐ Bước 1: Ktra đồ thị G có chu trình Euler hay ko? Nếu tồn cần tính tổng trọng số đồ thị(ta ko thể có lộ trình ngắn ta phải ghé thăm đỉnh lần) Ngược lại, ko tồn chu trình Euler tiếp tục thực Bước Bước 2: Tìm tất đỉnh có bậc lẻ Bước 3: Liệt kê tất cặp đỉnh bậc lẻ có (đối với n đỉnh bậc lẻ, tổng số cặp có (n-1)*(n-3)*(n-5)…*1 Bước 4: Đối với cặp ghép nối, tìm đường ngắn nối chúng Bước 5: Tìm cặp mà đường nối chúng ngắn nhỏ Bước 6: Cập nhật cạnh vừa tìm bước vào đồ thị G Bước 7: Độ dài ngắn tổng trọng số đồ thị G Bước 8: In mạch Euler đồ thị sửa đổi Kiểm nghiệm: Bước 1: Xét đồ thị trên, có deg(a)=deg(b)=deg(f)=deg(e)=3(lẻ) => ko có chu trình Euler Bước 2: Các đỉnh có bậc lẻ : A, B, E, F Bước 3: Các cặp đỉnh bậc lẻ có: [AE, BF], [AB, EF], [AF, BE] Bước 4: Đường ngắn nối cặp đỉnh: AE = AC + CE = 2+1 = BF = BD + DF = 1+1 = AB = EF = AF = AB+BD+DF = BE = BA+AC+CE = Bước 5: Cặp đỉnh có trọng số nhỏ mà qua đỉnh bậc lẻ tìm [ae, bf] Bước 6: Cập nhật đồ thị, ưu tiên cạnh có nhiều lần lặp lại trước Bước 7: Độ dài đường ngắn 28 Bước 8: Đường tìm : A-C-E-A-B-D-F-B-D-F-E-C–A III – Chương trình Bài tốn người đưa thư INPUT 031050 300106 100020 010001 502004 060140 OUTPUT 28 1351246246531 Cài đặt thuật toán #include using namespace std; #define MAX 50 struct DoubleVertex{ int weight; vector path; }; int V, len = 0; int a[MAX][MAX]; vector odd_vertex; vector cycle; map shortest_path; vector Set; bool used[MAX]; int x[10]; int res = 1e9; int deg[MAX]; int c[MAX][MAX]; // ham nhap gia tri void nhap(void){ cin >> V; cout