Đồ án giải thuật lập trình với đề tài sơ đồ mạng tại đại học bách khoa đà nẵng. Trong báo cáo bao gồm cách đọc file và xuất file từ định dạng cho trước,bao gồm code của chương trình. Báo cáo nhận được 9đ và rất đầy đủ,chỉ cần tải về và đọc hiểu code. Code được viết bằng java, tuy nhiên có thể viết bằng C hoặc C++.Mong các bạn đón nhận.
ĐẠI HỌC BÁCH KHOA KHOA CÔNG NGHỆ THÔNG TIN ĐỒ ÁN GIẢI THUẬT VÀ LẬP TRÌNH Đề tài : Sơ đồ mạng GIẢNG VIÊN HƯỚNG DẪN: Võ Đức Hoàng SINH VIÊN THỰC HIỆN: Phan Cao Minh Nhật LỚP SH: 18T1 NHÓM: 18.Nh10B Đà Nẵng, 18/12/2020 Đồ án Giải thuật Lập trình MỤC LỤC MỤC LỤC i LỜI MỞ ĐẦU ii DANH MỤC HÌNH VẼ .iii GIỚI THIỆU ĐỀ TÀI CƠ SỞ LÝ THUYẾT 2.1 Ý tưởng 2.2 Thuật tốn tìm khung nhỏ (Prim) .1 TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN 3.1 Phát biểu toán .3 3.2 Cấu trúc liệu 3.3 Thuật toán CHƯƠNG TRÌNH VÀ KẾT QUẢ 4.1 Tổ chức chương trình .7 4.2 Ngôn ngữ cài đặt 10 4.3 Kết 11 4.3.1 Giao diện chương trình 11 4.3.2 Kết thực thi chương trình 12 4.3.3 Nhận xét 12 KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN .13 5.1 Kết luận 13 5.2 Hướng phát triển .13 TÀI LIỆU THAM KHẢO 14 i Đồ án Giải thuật Lập trình LỜI MỞ ĐẦU Ngày nay, Cơng nghệ thơng tin trở thành ngành khoa học quan trọng sống đại, góp phần to lớn vào việc nâng cao suất, hiệu công việc cho ngành nghề khác Có thể nói, ngành khoa học khác cần đến trợ giúp máy vi tính Do đó, việc học tập nghiên cứu tin học trở nên cần thiết tất yếu người Đối với sinh viên ngành phải tích cực học tập, nắm vững kiến thức công nghệ thông tin, cấu trúc liệu giải thuật xem sở, tảng Cấu trúc liệu giải thuật giúp cho sinh viên hiểu tầm quan trọng giải thuật cách tổ chức cấu trúc liệu để giải toán cụ thể Trong học kỳ này, em giao thực Đồ án giải thuật lập trình Và đề tài em thực là: “Sơ đồ mạng” Trong trình thực đồ án chắn khó tránh khỏi sai sót, mong đóng góp ý kiến thầy, giáo khoa Và em xin chân thành gửi lời cảm ơn chân thần đến thầy, cô khoa, đặc biệt thầy Võ Đức Hồng tận tình hướng dẫn, tạo điều kiện cho em hoàn thành đề tài ii Đồ án Giải thuật Lập trình DANH MỤC HÌNH VẼ Figure 1: Ví dụ lời giải cho tốn sơ đồ mạng Figure 2: Ví dụ mảng chiều .6 Figure 3: Ví dụ chuyển liệu sang dạng ma trận .8 Figure 4: Dữ liệu vào từ file văn SoDoKetNoiKhuVaPhong.txt 11 Figure 5: Kết đưa file văn output.txt 12 iii Đồ án Giải thuật Lập trình GIỚI THIỆU ĐỀ TÀI Trường Đại học Bách Khoa bao gồm nhiều khu giảng đường khác Tổ quản trị mạng cần xây dựng sơ đồ mạng để kết nối tất khu với Các khu kết nối với số khu khác không Trong khu phịng kết nối với khơng Kèm theo độ dài chi phí dây mạng cần kết nối cho chi phí dây mạng dùng kết nối thấp Figure 1: Ví dụ lời giải cho toán sơ đồ mạng CƠ SỞ LÝ THUYẾT 2.1 Ý tưởng - Lúc đầu khung chứa khu chọn trước, sau thêm dần khu vào khung Mỗi lần chọn khu chưa nạp cho khu kề gần với khu thêm 2.2 Thuật tốn tìm khung nhỏ (Prim) Thuật toán xuất phát từ chứa đỉnh mở rộng bước một, bước thêm cạnh vào cây, bao trùm tất đỉnh đồ thị - Dữ liệu vào: Một đồ thị có trọng số liên thơng với tập hợp đỉnh V tập hợp cạnh E Đồng thời dùng V E để ký hiệu số đỉnh số cạnh đồ thị - Khởi tạo: Vmới = {x}, x đỉnh (đỉnh bắt đầu) V, Emới = {} Lặp lại Vmới= V: - Chọn cạnh (u, v) có trọng số nhỏ thỏa mãn u thuộc Vmới v khơng thuộc Vmới (nếu có nhiều cạnh chọn cạnh chúng) Đồ án Giải thuật Lập trình - Thêm v vào Vmới, thêm cạnh (u, v) vào Emới - Dữ liệu ra: Vmới Emới tập hợp đỉnh tập hợp cạnh bao trùm nhỏ - Ví dụ: Hình minh họa U Cạnh (u,v) {A,E} Mơ tả Đây đồ thị có trọng số {A,B,C,E,F} ban đầu Các số trọng số cạnh {} {A} V\U (A,E) = 100 X (A,C) = 150 (A,F) = 120 (A,F) = 120 (C,E) = 70 X {B,C,E,F} Chọn cách tùy ý đỉnh A đỉnh bắt đầu Các đỉnh C, F, E nối trực tiếp tới A cạnh đồ thị E đỉnh gần A nên ta chọn E đỉnh thứ hai thêm cạnh EA vào {B,C,F} Đỉnh chọn đỉnh gần A E C có khoảng cách tới A 150 tới E 70, F có khoảng cách tới A 120 C đỉnh gần nên chọn đỉnh C cạnh EC Đồ án Giải thuật Lập trình {A,E,C} {A,E,C,F} {A,E,C,F,B} (C,F) = 80 X (C,B) = 90 {B,F} (F,A) = 120 (F,B) = 50 V {B} (C,B) = 90 {} Thuật toán tiếp tục tương tự bước trước Chọn đỉnh F có khoảng cách tới C 80 Ở bước ta có đỉnh B Khoảng cách từ B tới F 50 tới C 90 Nên ta chọn đỉnh B cạnh FB Bây đỉnh nằm bao trùm nhỏ tô màu đỏ TỔ CHỨC CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN 3.1 Phát biểu toán - Dữ liệu vào: Tập tin chứa bảng mơ tả kết nối chi phí khu phịng + Ví dụ: Đồ án Giải thuật Lập trình Ký hiệu Khu Khu kết nối (5 khu):A,B,C,E,F A C(150) , E(100), F(120) B C(90) , F(50) C A(150) , B(90), E(70), F(80) Ký hiệu Phịng Phịng kết nối A101 A102(5) , A103(9), A201(12) A102 A202(12) , A135(15) C105 C205(12) … … - Dữ liệu ra: Tập tin chứa lưu trữ mạng kết nối Khu, Phịng với chi phí thấp + Ví dụ: Khu ket noi Chi phí F-B 50 E-C 70 A-E 100 C-F 80 => Chi phi ket noi thap nhat la: 300 3.2 Cấu trúc liệu 3.2.1 Mảng chiều - Mảng tập hợp phần tử có kiểu liệu phần tử lưu trữ dãy ô nhớ liên tục nhớ Các phần tử mảng truy cập cách sử dụng “chỉ số” Mảng có kích thước N có số từ tới N–1 Các phần tử mảng truy cập cách sử dụng array_name[index] - Trong ngôn ngữ Java, việc khai báo mảng thực theo cú pháp cần tham số: Dạng 1: [kiểu liệu] [] [tên mảng] ; Dạng 2: [kiểu liệu] [tên mảng] [] ; + Kích thước mảng: Việc xác định số lượng phần tử lưu trữ mảng Đồ án Giải thuật Lập trình + Kiểu liệu mảng: Việc định kiểu liệu phần tử mảng số nguyên, số thực, ký tự kiểu liệu - Cách tạo mảng chiều : Cách 1: kiểu_dữ_liệu] [] [tên_mảng] = new [kiểu_dữ_liệu] [kích_thước_mảng]; Cách 2: kiểu_dữ_liệu] [tên_mảng] [] = new [kiểu_dữ_liệu] [kích_thước_mảng]; - Trong tốn sử dụng mảng chiều: + tenKhuVaPhong : dùng để chứa tên khu trường tên phòng khu + point : dùng để tách khu chi phí kèm với khu file input + dinhCha : dùng để chứa đỉnh đỉnh cha đỉnh xét để tìm đỉnh cần thêm vào dựa vào chi phí đỉnh đỉnh cha + chiPhi: dùng để chứa chi phí đỉnh đỉnh cha + kiemTraDinh : dùng để kiểm tra đỉnh thêm vào khung hay chưa 3.2.2 Mảng chiều - Mảng hai chiều mảng mà phần tử mảng chiều, giống bảng gồm có dịng cột, đánh dấu vị trí số bao gồm số dịng số cột - Trong ngơn ngữ Java, mảng hai chiều khai báo theo cú pháp: Dạng 1: [kieu_du_lieu] [ten_mang] [][]; Dạng 2: [kieu_du_lieu] [][] [ten_mang] ; - Cách tạo mảng chiều : Cách 1: kiểu_dữ_liệu] [][] [tên_mảng] = new kiểu_dữ_liệu [số_dòng] [số_cột]; Cách 2: kiểu_dữ_liệu] [tên_mảng] [][] = new kiểu_dữ_liệu [số_dịng] [số_cột]; Trong đó: [kieu_du_lieu] mô tả kiểu phần tử thuộc mảng (như int, char, double, String, ), tên_mảng tên mảng quy tắc đặt tên phải tuân theo quy tắc đặt tên biến Java - Trong toán sử dụng mảng chiều : + mangCacKhu : dùng để chứa chi phí khu Ví dụ: int[][] mangCacKhu = new int[5][5]; Đồ án Giải thuật Lập trình Figure 2: Ví dụ mảng chiều 3.3 Thuật tốn Thuật tốn tìm khung nhỏ thuật toán Prim - Giải thuật + Ý tưởng thuật toán: Thuật toán xuất phát từ khung chứa khu mở rộng bước một, bước thêm cạnh vào khung, bao trùm tất khu Dãy ban đầu có n khu, tóm tắt ý tưởng thuật toán thực n-1 lần việc đưa khu vào khung Các bước thực sau: • Bước : Cho tất phần tử kiemTraDinh[] = false • Bước : Tìm khu u có chi phí thấp với khu cha Ở lần ta cho u phần tử mảng + Ở bước ta có vịng for chạy N-1 lần để tìm N-1 khu cần thêm vào khung nhỏ • Bước : Cho khu u vừa tìm true với kiemTraDinh[u] = true • Bước : Chạy vịng for N lần để tìm khu có kết nối với khu u vừa tìm được, sau quay lại bước Trong : - kiemTraDinh[] mảng chứa khu thêm vào với kiemTraDinh[u] = true với u khu có chi phí thấp với khu cha - N độ dài ma trận => Độ phức tạp thuật toán: từ bước ta thấy thuật tốn có vịng for lồng Khi chạy thuật tốn tốn N.(N-1) lần tìm khu cần thêm vào khung nhỏ Vậy thuật tốn có độ phức tạp O(N2) Đồ án Giải thuật Lập trình - Đánh giá giải thuật + Thuật tốn có độ phức cao, nhiên dễ cài đặt sử dụng tốt với toán với N nhỏ Với tốn với N lớn thuật tốn gặp vấn đề thời gian để giải toán CHƯƠNG TRÌNH VÀ KẾT QUẢ 4.1 Tổ chức chương trình 4.1.1 Hàm main() - Chức : + Đọc file SoDoKetNoiKhuVaPhong.txt ghi liệu file output.txt + Lấy dach sách khu phòng hàm getRoom() để lưu vào mảng + Chuyển liệu đọc sang dạng ma trận hàm chuyenSangMT() + Tìm chi phi thấp hàm hàm prim() đồng thời ghi liệu file output.txt - Chương trình : public static void main(String[] args) { DoAn t = new DoAn(); String[] tenKhuVaPhong = null; int[][] mangCacKhu = new int[20][20]; try { } //Ghi file tep output.txt FileWriter myWriter = new FileWriter("output.txt"); //Doc du lieu tu file SoDoKetNoiKhuVaPhong.txt File input = new File("SoDoKetNoiKhuVaPhong.txt"); Scanner number = new Scanner(input); //Xet tung dong file while(number.hasNextLine()) { String data = number.nextLine(); while(number.hasNextLine()) { String currentLine[]=data.trim().split("\\s+"); tenKhuVaPhong = t.getRoom(data, number); t.chuyenSangMT(mangCacKhu, currentLine, data, number, tenKhuVaPhong); t.prim(mangCacKhu,myWriter,tenKhuVaPhong); data = number.nextLine(); } } myWriter.close(); } catch(FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Đồ án Giải thuật Lập trình 4.1.2 Hàm chuyenSangMT() - Chức : + Chuyển liệu từ file đọc sang dạng ma trận với việc dùng hàm check() tach() * Ví dụ: Figure 3: Ví dụ chuyển liệu sang dạng ma trận + Hàm check() : kiểm tra phòng khu nằm vị trí mảng + Hàm tach() : dùng để tách phịng chi phí phịng lưu vào mảng point *Ví dụ : tach(“C(100),”) => point[0] = “C” , point[1] = 100 - Chương trình : + Hàm chuyenSangMT() : int[][] chuyenSangMT(int[][] zones, String[] currentLine, String data,Scanner number,String[] s){ data = number.nextLine(); int j = 0; while(data.length() != 0) { int k = 0; currentLine = data.trim().split("\\s+"); data = number.nextLine(); for(int i = 0; i < s.length; i++) { if(k < currentLine.length) { int a = check(tach(currentLine[k])[0],s); if(a == i) { if(a == j) { zones[j][i] = 0; } else { zones[j][i] = Integer.parseInt(tach(currentLine[k])[1]); zones[i][j] = zones[j][i]; } k++; }else { if(zones[j][i] == 0) { zones[j][i] = zones[i][j]; } } Đồ án Giải thuật Lập trình } } j++; } return zones; } + Hàm check() : int check(String a,String s[]) { for(int i = 0; i < s.length; i++) { if(s[i].equals(a)) { return i; } } return -1; } + Hàm tach() : String[] tach(String a) { if(a.length() == || a.length() == 4) { String[] point = {a,"0"}; return point; }else { int e = a.lastIndexOf("("); int f = a.lastIndexOf(")"); String x = a.substring(e + 1, f); String y = a.substring(0,e); String[] point = {y,x}; return point; } } 4.1.3 Hàm prim() - Chức : + Tìm chi phí thấp khu phòng với việc dùng thêm hàm chiChiThapNhat() hàm print() + Hàm chiChiThapNhat() : tìm chi phí thấp để thêm vào khung nhỏ + Hàm print() : ghi liệu tìm file output.txt - Chương trình : + Hàm prim() : void prim(int maTranPhongVaKhu[][],FileWriter myWriter,String[] khu) { int n = khu.length; int dinhCha[] = new int[n]; int chiPhi[] = new int[n]; Boolean kiemTraDinh[] = new Boolean[n]; for (int i = 0; i < n; i++) { chiPhi[i] = Integer.MAX_VALUE; kiemTraDinh[i] = false; } chiPhi[0] = 0; dinhCha[0] = -1; Đồ án Giải thuật Lập trình //Danh sách đỉ nh chọn n-1 for (int count = 0; count < n - 1; count++) { //Chọn khu có chi phí thấ p nhấ t chưa có khung int u = chiPhiThapNhat(chiPhi, kiemTraDinh, n); kiemTraDinh[u] = true; //Cập nhật đỉ nh liề n kềvới đỉ nh vừa chọn chưa có khung nhỏ nhấ t for (int v = 0; v < n; v++) if (maTranPhongVaKhu[u][v] != && kiemTraDinh[v] == false && maTranPhongVaKhu[u][v] < chiPhi[v]) { dinhCha[v] = u; chiPhi[v] = maTranPhongVaKhu[u][v]; } } //In file print(dinhCha,maTranPhongVaKhu,myWriter,khu); } + Hàm chiChiThapNhat() : int chiPhiThapNhat(int chiPhi[], Boolean kiemTraDinh[],int X) { int = Integer.MAX_VALUE, min_index = -1; } for (int v = 0; v < X; v++) if (kiemTraDinh[v] == false && chiPhi[v] < min) { = chiPhi[v]; min_index = v; } return min_index; + Hàm print() : void print(int dinhCha[], int maTranPhongVaKhu[][],FileWriter myWriter,String[] khu) { try { int a = 0; myWriter.write("\nKhu ket noi \tChi phí\n"); for(int i = 1; i < khu.length; i++) { myWriter.write( " " + khu[dinhCha[i]] + " - " + khu[i] + "\t\t" + maTranPhongVaKhu[i][dinhCha[i]] + "\n"); a = a + maTranPhongVaKhu[i][dinhCha[i]]; } myWriter.write("=> Chi phi ket noi thap nhat la: " + a + "\n"); } catch (IOException e) { e.printStackTrace(); } } 4.2 Ngơn ngữ cài đặt Chương trình sử dụng ngơn ngữ Java 10 Đồ án Giải thuật Lập trình 4.3 Kết 4.3.1 Giao diện chương trình Figure 4: Dữ liệu vào từ file văn SoDoKetNoiKhuVaPhong.txt - Trên hình file văn liệu đầu vào với kí hiệu Khu Phịng khu Cột bên trái thể cho kí hiệu khu phòng khu Cột bên phải thể cho khu phịng kết nối được, sau khu phịng chi phí kết nối khu phòng 11 Đồ án Giải thuật Lập trình 4.3.2 Kết thực thi chương trình Figure 5: Kết đưa file văn output.txt - Dựa vào hình ta thấy kết thực thi chưa trình Với cột bên trái thể cho khu phịng kết nối với mang chi phí thấp Cột bên phải thể cho chi phí kểt nối khu phòng Đồng thời kết thể chi phí thấp sau khu phòng 4.3.3 Nhận xét Ta thấy độ phức tạp chương trình O(V 2) , điều cho thấy chương trình chạy tương đối chậm Nếu đồ thị đầu vào sử dụng danh sách kề với giúp đỡ đống nhị phân độ phức tạp chương trình xuống cịn O(E log V) Nếu sử 12 Đồ án Giải thuật Lập trình dụng cấu trúc liệu đống Fibonacci phức tạp hơn, giảm thời gian chạy xuống O(E + V log V) KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 5.1 Kết luận - “Sơ đồ mạng” ví dụ điển hình việc kết hợp Giải thuật Cấu trúc liệu để giải tốn - Phương pháp tìm khung nhỏ thuật tốn Prim cho phép tìm sơ đồ kết nối khu phòng với chi phí thấp với vài dịng lệnh, bên cạnh phương pháp chưa tối ưu độ phức tạp lớn Nên sơ đồ lớn việc sử dụng giải thuật tỏ chậm - Việc sử dụng cấu trúc liệu đống nhị phân Fibonacci phức tạp nhiên giải tối ưu toán “Sơ đồ mạng” Điề u giúp tốn hướng tới việc tìm kết nhanh hơn, chiếm dụng nhớ 5.2 Hướng phát triển Bài toán “Sơ đồ mạng” áp dụng cho cơng trình lớn Ví dụ Google Map cách tìm đường ngắn cho người dùng dùng để tính tốn mạng lưới điện quốc gia Các biến đổi tăng số lượng đỉnh khung 13 Đồ án Giải thuật Lập trình TÀI LIỆU THAM KHẢO Thuật toán Prim Bài giảng Toán rời rạc – Phan Thanh Tao Giáo trình Phân tích thiết kế giải thuật - Phan Chí Tùng 4.Prim’s Minimum Spanning Tree (MST) 14