SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 33 - không âm hoặc đồ thị không có chu trình. Trong trường hợp tổng quát , sử dụng thuật toán Ford-Bellman n lần không phải là cách làm tốt nhất . Ở đây ta sẽ mô tả thuật toán với độ phức tạp tính toán O(n 3 ) : thuật toán Floyd, tt được mô tả như sau Procedure Floyd; (* Tìm đường đi ngắn nhất giữa tất cả các cặp đỉnh Đầu vào : Đồ thị cho bởi ma trận trọng số a[i,j], i,j=1,2, ,n Đầu ra : Ma trận đường đi ngắn nhất giữa các cặp đỉnh d[i,j] i,j =1,2, ,n trong đó d[i,j] cho độ dài đường di ngắn nhất từ i đến j. Ma trận ghi nhận đường đi p[i,j], i, j=1,2, ,n. trong đó p[i,j] ghi nhận đỉnh đi trước j trong đường đi ngắn nhất từ i đến j. *) Begin (* Khởi tạo *) For i:=1 to n do For j:=1 to n do Begin d[i,j]:=a[i,j]; SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 34 - p[i,j]:=i; end; (* Bước lặp *) For k:=1 to n do For i:=1 to n do For j:=1 to n do If d[i,j] > d[i,k] + d[k,j] then Begin d[i,j]:= d[i,k] + d[k,j ]; p [i,j ]:= p [k,j ]; end; end; Rõ ràng độ phức tạp của thuật toán là O(n 3 ). Chương II : GIẢI THUẬT_LƯU ĐỒ THUẬT TOÁN DIJKSTRA II.1 Phân tích. Dùng ma trận kề để biểu diễn đồ thị C= (cij), cij = trọng số của cung (i,j), cij =+ ∞ nếu không có cung (i,j). Một mảng d[] để ghi các độ dài đường đi ngắn nhất từ s tới đỉnh i đang có . Xuất phát d[s] =0 và d[i] =c si nếu i kề s, d[j] =+ ∞ nếu j không kề s. SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 35 - II.2 Giải thuật tìm đường đi ngắn nhất giữa một cặp đỉnh. Định nghĩa 1.0. Xét đồ thị có trọng số cạnh G = (V,E,w), với hàm trọng số w:E R là ánh xạ từ tập các cạnh E đến tập số thực R. Định nghĩa 1.1. Đường đi p từ đỉnh u đến đỉnh v là dãy các cạnh nối tiếp nhau bắt đầu từ đỉnh u kết thúc tại đỉnh v. Đường đi p từ u đến v được biểu diễn như sau: p=(u=v 0 ,v 1 …,v k =v) Định nghĩa 1.2. Độ dài của đường đi p = ( v 0 ,v 1 , ,v k ), ký hiệu (p), là tổng các trọng số của các cạnh trên đường đi: (p) = k i ii vvw 1 1 ),( Định nghĩa 1.3. Gọi (u,v) là tập tất cả đường đi từ u đến v. Độ dài đường đi ngắn nhất từ đỉnh u đến đỉnh v được xác định bởi: d(u,v) = vupp )},(|)({min Định nghĩa 1.4. Đường đi ngắn nhất p min (u,v) từ đỉnh u đến đỉnh v là đường đi có độ dài d(u,v). II.3 Giải thuật Dijkstra. II.3.1 Nội dung SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 36 - Có rất nhiều giải thuật đã được phát triển để giải bài toán tìm đường đi ngắn nhất giữa một cặp đỉnh, trong khuôn khổ bài viết này em chỉ xin giới thiệu giải thuật Dijkstra. Giải thuật Dijkstra là một giải thuật để giải bài toán đường đi ngắn nhất nguồn đơn trên một đồ thị có trọng số cạnh mà tất cả các trọng số đều không âm. Nó xác định đường đi ngắn nhất giữa hai đỉnh cho trước, từ đỉnh a đến đỉnh b. Ở mỗi đỉnh v, giải thuật Dijkstra xác định 3 thông tin: k v , d v và p v . k v : mang giá trị boolean xác định trạng thái được chọn của đỉnh v. Ban đầu ta khởi tạo tất cả các đỉnh v chưa được chọn, nghĩa là: k v = false, v V. d v : là chiều dài đường đi mà ta tìm thấy cho đến thời điểm đang xét từ a đến v. Khởi tạo, d v = , v V \{a}, d a = 0. p v : là đỉnh trước của đỉnh v trên đường đi ngắn nhất từ a đến b. Đường đi ngắn nhất từ a đến b có dạng {a, ,p v ,v, ,b}. Khởi tạo, p v = null, v V. Sau đây là các bước của giải thuật Dijkstra: B1. Khởi tạo: Đặt k v := false v V; d v := ,v V \ {a}, d a :=0. B2. Chọn v V sao cho k v = false và d v = min {d t / t V, k t = false} Nếu d v = thì kết thúc, không tồn tại đường đi từ a đến b. B3. Đánh dấu đỉnh v, k v: = true. SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 37 - B4. Nếu v = b thì kết thúc và d b là độ dài đường đi ngắn nhất từ a đến b. Ngược lại nếu v b sang B5. B5. Với mỗi đỉnh u kề với v mà k u = false, kiểm tra Nếu d u > d v + w(v,u) thì d u := d v + w(v,u) Ghi nhớ đỉnh v: p u := v.Quay lại B2. II.3.2 Độ phức tạp của giải thuật Dijkstra. *** Trường hợp sử dụng ma trận kề. Gọi f(n) là số lần giải thuật Dijkstra khảo sát một cạnh của đồ thị G trong trường hợp xấu nhất. Khi đó ta có: f(n) < O(|V| 2 ) Chứng minh: Cho n = |V|, B5 là vòng lặp chứa các bước B2 B5, vòng lặp được thực hiện đến khi v = b.Vì ở mỗi vòng lặp ta rút ra một đỉnh của V và khởi đầu V có n phần tử, nên vòng lặp được xử lý nhiều nhất là n lần. Ở B2 số đỉnh tối đa được khảo sát là n - 1 đỉnh Ở B5 số đỉnh kề tối đa được khảo sát là n -1 đỉnh Do đó: f(n) 2(n-1)n < O(|V| 2 ) Vậy độ phức tạp của giải thuật Dijkstra là O(|V| 2 ). *** Trường hợp sử dụng danh sách kề Độ phức tạp của giải thuật Dijkstra là O((|V| + |E|)lg|V|). II.3.3 Lưu đồ thuật toán Dijstra SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 38 - Begin n, C = (c ij ), a, z L(a) = 0 L(v) = v a T(i) = 1 i n z T Chọn v T sao cho L[v] đạt min T = T \ {v} x T & kề v L(x) = min(L(x), L(v) + c(v,x)) End S Đ S Đ L(z) SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 39 - II.3.4 Bảng dữ liệu chạy thô. Tạo ma trận như sau 6 0 4 2 0 0 0 4 0 1 5 0 0 2 1 0 8 10 0 0 5 8 0 2 6 0 0 10 2 0 3 0 0 0 6 3 0 Ta có đồ thị như sau b 5 c 4 6 a d 1 8 2 10 3 e f Bảng chạy thô SVTH : Nguyễn Công Hiếu_SBD 0041 - Trang 40 - V T a b e c f d 0 a bcdef * 4 2* e bcfd 3* * 10 12 b cfd * 8* 12 c fd * 12* 14 f d * 15 d * độ dài từ af là 15 . hoặc đồ thị không có chu trình. Trong trường hợp tổng quát , sử dụng thuật toán Ford-Bellman n lần không phải là cách làm tốt nhất . Ở đây ta sẽ mô tả thuật toán với độ phức tạp tính toán O(n 3 ). end; Rõ ràng độ phức tạp của thuật toán là O(n 3 ). Chương II : GIẢI THUẬT_LƯU ĐỒ THUẬT TOÁN DIJKSTRA II.1 Phân tích. Dùng ma trận kề để biểu diễn đồ thị C= (cij), cij = trọng số của cung. độ phức tạp tính toán O(n 3 ) : thuật toán Floyd, tt được mô tả như sau Procedure Floyd; (* Tìm đường đi ngắn nhất giữa tất cả các cặp đỉnh Đầu vào : Đồ thị cho bởi ma trận trọng số a[i,j],