Tiểu luận tìm cây phủ chiều ngang

21 337 6
Tiểu luận tìm cây phủ chiều ngang

Đ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

Lý thuyết đồ thị là một lĩnh vực nghiên cứu đã có từ lâu và có nhiều ứng dụng trong ngành công nghệ thông tin. Những tư tưởng cơ bản của lý thuyết đồ thị được đề xuất vào những năm đầu của thế kỷ 18 bởi nhà toán học lỗi lạc người Thụy Sỹ: Leonhard Euler. Chính ông là người đã sử dụng đồ thị để giải bài toán nổi tiếng về 7 cái cầu ở thành phố Konigberg.Lý thuyết đồ thị có rất nhiều bài toán được ứng dụng có hiệu quả trong nhiều lĩnh vực. Một trong những bài toán đó chính là bài toán tìm cây phủ của đồ thị.Để ứng dụng phần lý thuyết đã học về Toán ứng dụng vào trong đề tài của tiểu luận, em trình bày hai vấn đề :Thuật toán tìm cây phủ của đồ thị theo chiều ngang.Áp dụng thuật toán trên cho đồ thị không liên thông.

ĐẠI HỌC ĐÀ NẴNG TRƯỜNG ĐẠI HỌC BÁCH KHOA ĐÀ NẴNG - - TIỂU LUẬN MÔN: TOÁN ỨNG DỤNG ĐỀ TÀI THUẬT TOÁN TÌM CÂY PHỦ THEO CHIỀU NGANG GV hướng dẫn : PGS.TSKH Trần Quốc Chiến Học viên : Nguyễn Trọng Ân Chuyên ngành : Khoa Học Máy Tính Khóa : 30 ĐÀ NẴNG, 06/2015 LỜI MỞ ĐẦU Lý thuyết đồ thị lĩnh vực nghiên cứu có từ lâu có nhiều ứng dụng ngành công nghệ thông tin Những tư tưởng lý thuyết đồ thị đề xuất vào năm đầu kỷ 18 nhà toán học lỗi lạc người Thụy Sỹ: Leonhard Euler Chính ông người sử dụng đồ thị để giải toán tiếng cầu thành phố Konigberg Lý thuyết đồ thị có nhiều toán ứng dụng có hiệu nhiều lĩnh vực Một toán toán tìm phủ đồ thị Để ứng dụng phần lý thuyết học Toán ứng dụng vào đề tài tiểu luận, em trình bày hai vấn đề :  Thuật toán tìm phủ đồ thị theo chiều ngang  Áp dụng thuật toán cho đồ thị không liên thông Em xin chân thành cảm ơn thầy PGS.TSKH Trần Quốc Chiến hướng dẫn cung cấp kiến thức tài liệu để em hoàn thành tiểu luận Học viên thực Nguyễn Trọng Ân MỤC LỤC LỜI MỞ ĐẦU CHƯƠNG I ĐẠI CƯƠNG VỀ ĐỒ THỊ CÂY I.Định nghĩa 1 Định nghĩa Định nghĩa Định nghĩa 2 II.Tính chất Định lý (Định lý tương đương) 2 Định lý .2 III.Cây m-phân .3 Định nghĩa Định lý .3 Hệ Định lý .3 CÂY PHỦ .3 I.Định nghĩa II.Định lý 4 CHƯƠNG II BÀI TOÁN TÌM CÂY PHỦ THEO CHIỀU NGANG I.Giới thiệu toán CHƯƠNG III THIẾT KẾ VÀ CÀI ĐẶT BÀI TOÁN I.Thuật toán II.Thiết kế cấu trúc liệu 1.Dữ liệu đầu vào 2.Dữ liệu đầu 3.Hàng đợi Q 4.Cây phủ SpanningTree III.Áp dụng thuật toán cho đồ thị không liên thông .8 1.Ý tưởng IV.Cài đặt toán KẾT LUẬN 16 TÀI LIỆU THAM KHẢO 17 CHƯƠNG I ĐẠI CƯƠNG VỀ ĐỒ THỊ CÂY I Định nghĩa Định nghĩa Cây đồ thị liên thông không chứa chu trình Ví dụ 3.1.1 Đồ thị sau v1 v2 v4 v3 v5 v6 v7 Gốc đỉnh đặc biệt, thông thường đỉnh Mức đỉnh độ dài đường từ gốc lên đỉnh Độ cao mức lớn ( tức mức đỉnh cách xa gốc nhất) Trong ví dụ ta chọn v1 gốc v2, v3 định mức 1, đỉnh v4, v5, v6, v7 có mức 2, độ cao 2 Định nghĩa Cho T có gốc v0 Giả sử x, y, z đỉnh T ( v0, v 1,…,vn) đường từ v0 đến T ta gọi Vn-1 cha V0, …, vn-1 tiền bối Vn vn-1 y hậu x, x tiền bối y y z anh em chúng đỉnh x x đỉnh x đỉnh có Định nghĩa Rừng đồ thị mà thành phần liên thông Ví dụ 3.1.2 Đồ thị sau rừng có II Tính chất Định lý (Định lý tương đương) Cho T đồ thị n đỉnh Các mệnh đề sau tương đương T T không chứa chu trình có n-1 cạnh T liên thông có n-1 cạnh T liên thông cạnh cầu Hai đỉnh nối với đường T không chứa chu trình thêm cạnh nối hai đỉnh ta thu chu trình T liên thông them cạnh nối hai đỉnh ta thu chu trình Định lý Tâm tập hợp có đỉnh có hai đỉnh kề III Cây m-phân Định nghĩa Cây m-phân ( m ∈ N*) mà đỉnh có tối đa m có đỉnh có m Cây m-phân đầy đủ mà đỉnh có m Cây cân mà đỉnh có mức h hay h-1, h chiều cao Định lý Nếu m-phân đầy đủ có i đỉnh trong, m.i+1 (=n) đỉnh Hệ Cho T m-phân đầy đủ có i đỉnh trong, l đỉnh n đỉnh Khi : l = (m -1).i + i= & n= i= & l= Định lý Cho T m-phân có l chiều cao h Nếu T m-phân cân đầy đủ h= [logml] Trong [x] (trần nguyên x) ký hiệu số nguyên nhỏ lớn x CÂY PHỦ I Định nghĩa Cho đồ thị G=(V,E) Cho T gọi phủ hay bao trùm G, T đồ thị phủ G Ví dụ: Các T1 T2 phủ đồ thị G G II T1 T2 Định lý Đồ thị G=(V,E) có phủ G liên thông CHƯƠNG II BÀI TOÁN TÌM CÂY PHỦ THEO CHIỀU NGANG I Giới thiệu toán Cho đồ thị bất kỳ, tìm phủ đồ thị Đầu vào toán tập thông tin số cạnh, số đỉnh cạnh đồ thị Đầu toán tập thông tin số thành phần liên thông, đinh cạnh phủ đồ thị liên thông đồ thị CHƯƠNG III THIẾT KẾ VÀ CÀI ĐẶT BÀI TOÁN I Thuật toán Trong giải thuật ta kí hiệu Q hàng đợi (queue) đỉnh, Ke(x) danh sách đỉnh kề x Đầu vào: Đồ thị G=(V,E) Đầu ra: Cây phủ T kết luận đồ thị không liển thong Các bước: (1) Khởi tạo: Chọn đỉnh Vi Khởi tạo hàng đợi Q:=[Vi], T đồ thị gồm đỉnh Vi cạnh, Vi gốc (2) Thêm cạnh: Rút đỉnh x ∈ Q Duyệt đỉnh y ∈ Ke(x), y ∉ T thêm cạnh (x,y) đỉnh y vào T đẩy y vào hàng đợi Q Nếu Q ≠ ∅ T chưa phủ hết đỉnh, quay lại bước 2, ngược lại sang bước (3) Kết luận: Nếu T phủ hết đỉnh đồ thị, T phủ, ngược lại đồ thị không liên thông II Thiết kế cấu trúc liệu Dữ liệu đầu vào File liệu đầu vào: GRAPH.INP có cấu trúc n m (số đỉnh, số cạnh) a1 b1 (đỉnh đầu, đỉnh cuối) a2 b2 … am bm Dữ liệu đầu File kết quả: GRAPH.OUT k {số thành phần liên thông} x1, , xi {các đỉnh thành phần liên thông thứ 1} (u1, v1),(u2, v2), {các cạnh phủ thành phần liên thông thứ 1} y1, , yj {các đỉnh thành phần liên thông thứ 2} (r1, t1), (r2, t2), … {các cạnh phủ thành phần liên thông thứ Hàng đợi Q typedef struct Queue { int capacity; int size; int front; int rear; int *elements; }Queue; Hàng đợi Queue có thuộc tính: - Capacity: kiểu integer, số phần tử tối đa mà queue chứa - Size: kiểu integer, số phần tử mà queue chứa - Front: kiểu integer, vị trí phần tử queue - Rear: kiểu integer, vị trí phần tử sau queue Cây phủ SpanningTree typedef struct SpanningTree { int mT[MAX]; int mCountT; int mSpanningEdges[MAX*2][2]; int mCountSpanningEdges; }SpanningTree; Cây phủ Cây phủ SpanningTree có thuộc tính: - mT: kiểu mảng integer, tập hợp đỉnh duyệt qua - mCount: kiểu integer, số phần tử mảng mT - mSpanningEdges: kiểu mảng hai chiều integer, tập hợp cạnh phủ - mCountSpanningEdges: kiểu integer, số phần tử mảng mSpanningEdges Kết toán tập phủ SpanningTree, số phần tử tập đồ thị có phủ, ngược lại lớn 1, đồ thị không liên thông tập tập rừng phủ đồ thị III Áp dụng thuật toán cho đồ thị không liên thông Ý tưởng Đối với toán tức đồ thị liên thông, duyệt hết đỉnh cạnh hàng đợi Q rỗng, ta kiểm tra tập đỉnh T phủ đồ thị hết chưa cách so sánh số lượng phần tử T(countT) số đỉnh đồ thị(n) countT == n Nếu trả true, tức đồ thị liên thông có tập phủ Ngược lại, trả false, đồ thị không liên thông Nếu đồ thị không liên thông, ta tìm rừng phủ cho đồ thị theo bước sau: (1) Thêm tập T kết vào tập phủ SpanningTree Trong tập cạnh đầu vào hàm tìm phủ, loại cạnh chứa đỉnh tồn tập T (2) Gọi hàm tìm phủ với tập cạnh đầu vào có, kết trả false, lặp lại bước 1, ngược lại sang bước (3) Thêm tập T kết vào tập phủ SpanningTree Kết thúc IV Cài đặt toán #include #include #include #define MAX 20 typedef struct SpanningTree{ int mT[MAX]; int mCountT; int mSpanningEdges[MAX*2][2]; int mCountSpanningEdges; }SpanningTree; void SpanningTreeToArray(SpanningTree ST[], int &countST, int T[], int countT, int SpanningEdges[][2], int countSpanningEdges) { for(int i = 0; i < countT; i++){ ST[countST].mT[i] = T[i]; } for(int i = 0; i < countSpanningEdges; i++){ for (int j = 0; j < 2; j ++ ){ ST[countST].mSpanningEdges[i][j] = SpanningEdges[i][j]; } } ST[countST].mCountT = countT; ST[countST++].mCountSpanningEdges = countSpanningEdges; } /*Queue has five properties capacity stands for the maximum number of elements Queue can hold Size stands for the current size of the Queue and elements is the array of elements front is the index of first element (the index at which we remove the element) and rear is the index of last element (the index at which we insert the element) */ typedef struct Queue { int capacity; int size; int front; int rear; int *elements; }Queue; /* createQueue function takes argument the maximum number of elements the Queue can hold, creates a Queue according to it and returns a pointer to the Queue */ Queue * CreateQueue(int maxElements) { /* Create a Queue */ Queue *Q; Q = (Queue *)malloc(sizeof(Queue)); /* Initialise its properties */ Q->elements = (int *)malloc(sizeof(int)*maxElements); Q->size = 0; Q->capacity = maxElements; Q->front = 0; Q->rear = -1; /* Return the pointer */ return Q; } void Dequeue(Queue *Q) { /* If Queue size is zero then it is empty So we cannot pop */ if(Q->size==0) { printf("Queue is Empty\n"); return; } /* Removing an element is equivalent to incrementing index of front by one */ else { Q->size ; Q->front++; /* As we fill elements in circular fashion */ if(Q->front==Q->capacity) { Q->front=0; } } return; } 10 void Enqueue(Queue *Q,int element) { /* If the Queue is full, we cannot push an element into it as there is no space for it.*/ if(Q->size == Q->capacity) { printf("Queue is Full\n"); } else { Q->size++; Q->rear = Q->rear + 1; /* As we fill the queue in circular fashion */ if(Q->rear == Q->capacity) { Q->rear = 0; } /* Insert the element in its rear side */ Q->elements[Q->rear] = element; } return; } bool CheckExist(int T[], int m, int n){ for(int i = 0; i < m; i++){ if(T[i] == n){ return true; } } return false; } void ReadFromAFile(int a[][2], int &n, int &m){ FILE *f; f=fopen("GRAPH.INP", "r"); fscanf(f, "%d", &n); fscanf(f, "%d", &m); for(int i = 0; i < m; i++){ for (int j = 0; j < 2; j ++ ){ fscanf(f, "%d", &a[i][j]); } } fclose(f); } 11 void WriteToAFile(SpanningTree ST[], int countST){ FILE *f; f=fopen("GRAPH.OUT", "w+"); fprintf(f, "%d ", countST); fprintf(f, "\n"); for(int i = 0; i< countST; i++){ for(int j = 0; j < ST[i].mCountT; j++){ if(j != ST[i].mCountT - 1){ fprintf(f, "%d, ", ST[i].mT[j]); }else{ fprintf(f, "%d ", ST[i].mT[j]); } } fprintf(f, "\n"); for(int j = 0; j < ST[i].mCountSpanningEdges; j++){ if(j != ST[i].mCountSpanningEdges - 1){ fprintf(f, "(%d, %d), ", ST[i] mSpanningEdges[j][0], ST[i] mSpanningEdges[j] [1]); }else{ fprintf(f, "(%d, %d) ", ST[i] mSpanningEdges[j][0], ST[i] mSpanningEdges[j][1]); } } fprintf(f, "\n"); } fclose(f); } void NewInputGraph(int a[][2], int &n, int &m, int T[], int countT, int a2[][2], int &n2, int &m2){ n2 = n - countT; int flag[m]; for(int j = 0; j < m; j++){ flag[j] = 0; } for(int i = 0; i < countT; i++){ for(int j = 0; j < m; j++){ if(a[j][0] == T[i] || a[j][1] == T[i]){ flag[j] = 1; } } } for(int j = 0; j < m; j++){ if(flag[j]==0){ a2[m2][0] = a[j][0]; a2[m2++][1] = a[j][1]; } } } 12 bool BFSSpanningTree(int a[][2], int n, int m, int T[], int &countT, int SpanningEdges[][2], int &countSpanningEdges) { Queue *Q = CreateQueue(MAX); Enqueue(Q, a[0][0]); T[countT++] = a[0][0]; int currentEdge = 0; int currentVertice; int nextVertice; while(Q->size > 0) { currentVertice = Front(Q); printf("Dang duyet dinh %d\n", currentVertice); Dequeue(Q); for(int i = 0; i < m; i++){ for (int j = 0; j < 2; j ++ ){ if(a[i][j]==currentVertice){ if(j==0){ nextVertice=a[i][1]; }else{ nextVertice=a[i][0]; } if(CheckExist(T, n, nextVertice)==false){ T[countT++]=nextVertice; //printf("Dang duyet nextVertice %d\n", nextVertice); SpanningEdges[countSpanningEdges][0]=a[i][0]; SpanningEdges[countSpanningEdges++][1]=a[i] [1]; Enqueue(Q, nextVertice); } } } } } if(countT == n){ return true; }else{ return false; } } 13 int main() { printf("***********************************************\n"); printf("\n"); printf("TIM CAY PHU THEO CHIEU NGANG\n"); printf("Hoc vien: NGUYEN TRONG AN\n"); printf("Lop: K30 KHMT\n"); printf("\n"); printf("***********************************************\n"); printf("\n"); printf("\n"); int a[MAX][2]; int n, m; int SpanningEdges[MAX][2]; printf("Doc file input GRAPH.INP \n"); ReadFromAFile(a, n, m); int T[MAX]; int countT = 0; int countSpanningEdges = 0; printf("So dinh: %d\n", n); printf("So canh: %d\n", m); printf("Dang xu ly \n"); int countLT = 0; SpanningTree ST[MAX]; int countST = 0; bool result = BFSSpanningTree(a, n, m, T, countT, SpanningEdges, countSpanningEdges); if(result){ SpanningTreeToArray(ST, countST, T, countT, SpanningEdges, countSpanningEdges); }else{ SpanningTreeToArray(ST, countST, T, countT, SpanningEdges, countSpanningEdges); int a2[MAX][2]; int n2=0, m2=0; NewInputGraph( a, n, m, T, countT, a2, n2, m2); countT = 0; countSpanningEdges = 0; result = BFSSpanningTree(a2, n2, m2, T, countT, SpanningEdges, countSpanningEdges); while(result == false){ SpanningTreeToArray(ST, countST, T, countT, SpanningEdges, countSpanningEdges); 14 NewInputGraph( a, n, m, T, countT, a2, n2, m2); countT = 0; countSpanningEdges = 0; result = BFSSpanningTree(a2, n2, m2, T, countT, SpanningEdges, countSpanningEdges); } SpanningTreeToArray(ST, countST, T, countT, SpanningEdges, countSpanningEdges); } printf("So phan lien thong: %d\n", countST); if(countST == 1){ printf("Do thi co cay phu Da ghi ket qua file GRAPH.OUT \n"); }else{ printf("Do thi khong lien thong Rung phu da duoc ghi file GRAPH.OUT \n"); } WriteToAFile(ST, countST); printf("Ket thuc.\n"); getch(); return 0; } 15 KẾT LUẬN  Em nắm bắt phần lý thuyết đồ thị toán ứng dụng  Xây dựng thuật toán tìm phủ theo chiều ngang  Áp dụng thuật toán cho toán đồ thị không liên thông 16 TÀI LIỆU THAM KHẢO [1] PGS.TSKH Trần Quốc Chiến – Bài Giảng Toán Ứng Dụng – Trường Đại Học Bách Khoa Đà Nẵng - 2015 [2] Các tài liệu Internet 17 [...]... thì trả về true, tức là đồ thị liên thông và có tập phủ Ngược lại, trả về false, đồ thị không liên thông Nếu đồ thị không liên thông, ta đi tìm rừng phủ cho đồ thị theo các bước sau: (1) Thêm tập T kết quả vào tập các cây phủ SpanningTree Trong tập các cạnh đầu vào của hàm tìm cây phủ, loại các cạnh chứa đỉnh đã tồn trong tập T (2) Gọi hàm tìm cây phủ với tập các cạnh đầu vào mới có, nếu kết quả trả... cùng của queue 4 Cây phủ SpanningTree typedef struct SpanningTree { int mT[MAX]; int mCountT; int mSpanningEdges[MAX*2][2]; int mCountSpanningEdges; }SpanningTree; Cây phủ Cây phủ SpanningTree có 4 thuộc tính: - mT: kiểu mảng integer, chỉ tập hợp các đỉnh đã duyệt qua - mCount: kiểu integer, chỉ số phần tử của mảng mT 7 - mSpanningEdges: kiểu mảng hai chiều integer, chỉ tập hợp các cạnh phủ đã - mCountSpanningEdges:... của bài toán là tập các cây phủ SpanningTree, nếu số phần tử của tập này là 1 thì đồ thị có cây phủ, ngược lại lớn hơn 1, đồ thị không liên thông và tập này là tập rừng phủ của đồ thị III Áp dụng thuật toán cho đồ thị không liên thông 1 Ý tưởng Đối với bài toán đúng tức là đồ thị liên thông, khi duyệt hết các đỉnh và các cạnh và hàng đợi Q rỗng, ta kiểm tra tập đỉnh trong T đã phủ đồ thị hết chưa bằng... khong lien thong Rung phu da duoc ghi ra file GRAPH.OUT \n"); } WriteToAFile(ST, countST); printf("Ket thuc.\n"); getch(); return 0; } 15 KẾT LUẬN  Em đã nắm bắt được một phần lý thuyết cơ bản về đồ thị toán ứng dụng  Xây dựng được thuật toán tìm cây phủ theo chiều ngang  Áp dụng thuật toán cho bài toán đồ thị không liên thông 16 TÀI LIỆU THAM KHẢO [1] PGS.TSKH Trần Quốc Chiến – Bài Giảng Toán Ứng Dụng...File kết quả: GRAPH.OUT k {số thành phần liên thông} x1, , xi {các đỉnh của thành phần liên thông thứ 1} (u1, v1),(u2, v2), {các cạnh cây phủ của thành phần liên thông thứ 1} y1, , yj {các đỉnh của thành phần liên thông thứ 2} (r1, t1), (r2, t2), … 3 {các cạnh cây phủ của thành phần liên thông thứ 2 Hàng đợi Q typedef struct Queue { int capacity; int size; int front; int rear; int *elements; }Queue;... loại các cạnh chứa đỉnh đã tồn trong tập T (2) Gọi hàm tìm cây phủ với tập các cạnh đầu vào mới có, nếu kết quả trả về false, lặp lại bước 1, ngược lại sang bước 3 (3) Thêm tập T kết quả vào tập các cây phủ SpanningTree Kết thúc IV Cài đặt bài toán 8 #include #include #include #define MAX 20 typedef struct SpanningTree{ int mT[MAX]; int mCountT; int mSpanningEdges[MAX*2][2];... nextVertice); } } } } } if(countT == n){ return true; }else{ return false; } } 13 int main() { printf("***********************************************\n"); printf("\n"); printf("TIM CAY PHU THEO CHIEU NGANG\ n"); printf("Hoc vien: NGUYEN TRONG AN\n"); printf("Lop: K30 KHMT\n"); printf("\n"); printf("***********************************************\n"); printf("\n"); printf("\n"); int a[MAX][2]; int n, ... Ví dụ: Các T1 T2 phủ đồ thị G G II T1 T2 Định lý Đồ thị G=(V,E) có phủ G liên thông CHƯƠNG II BÀI TOÁN TÌM CÂY PHỦ THEO CHIỀU NGANG I Giới thiệu toán Cho đồ thị bất kỳ, tìm phủ đồ thị Đầu vào... lĩnh vực Một toán toán tìm phủ đồ thị Để ứng dụng phần lý thuyết học Toán ứng dụng vào đề tài tiểu luận, em trình bày hai vấn đề :  Thuật toán tìm phủ đồ thị theo chiều ngang  Áp dụng thuật... phần tử sau queue Cây phủ SpanningTree typedef struct SpanningTree { int mT[MAX]; int mCountT; int mSpanningEdges[MAX*2][2]; int mCountSpanningEdges; }SpanningTree; Cây phủ Cây phủ SpanningTree

Ngày đăng: 22/12/2015, 20:10

Từ khóa liên quan

Mục lục

  • LỜI MỞ ĐẦU

  • CHƯƠNG I

  • ĐẠI CƯƠNG VỀ ĐỒ THỊ

  • CÂY

  • I. Định nghĩa

    • 1. Định nghĩa 1

    • 2. Định nghĩa 2

    • 3. Định nghĩa 3

    • II. Tính chất

      • 1. Định lý 1 (Định lý tương đương)

      • 2. Định lý 2

      • III. Cây m-phân

        • 1. Định nghĩa

        • 2. Định lý 1

        • 3. Hệ quả

        • 4. Định lý 2

        • CÂY PHỦ

        • I. Định nghĩa

        • II. Định lý

        • CHƯƠNG II

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

Tài liệu liên quan