Giáo án môn: Lý Thuyết Đồ Thị Nguyễn Minh Đức - ĐHQG Hà Nội 60 v1 v2 v10 v5 v8 v9 v6 v7 v3 v4 Chng 6 MT S BI TON NG DNG (Bi toỏn tỡm ng i ngn nht v bi toỏn lung cc i) 6.1 Bi toỏn tỡm ng i ngn nht 6.1.1 Tỡm ng i ngn nht trong th khụng cú trng s Bi toỏn: Cho th khụng cú trng s G = (V,E) v hai nh u, v V. Tỡm ng i ngn nht t nh u n nh v, tc l ng i t u n v cú s cnh (cung) l ớt nht gii quyt bi toỏn ny ta cú th thc hin theo thut toỏn sau õy: Thut toỏn: Bc 1: Ti nh u ta ghi s 0 Cỏc nh k vi u (cú cnh i t u n) ta ghi s 1 Cỏc nh k vi cỏc nh ó c ghi s 1 ta ghi s 2 Gi s ta ó ghi ti i, tc l ta ó ỏnh s c cỏc tp nh l V(0) = {u}, V(1), V(2), ,V(i). Trong ú V(i) l tp tt c cỏc nh c ghi bi s i. Ta xỏc nh tp cỏc nh c ỏnh s bi s i+1 nh sau: V(i+1) = {x| x V, x V(k) vi k=0,1, ,i v yV(i) sao cho t y cú cnh (cung) i ti x} Do tớnh hu hn ca th, sau mt s hu hn bc, thut toỏn dng li v cho ta tp cỏc nh cú cha nh v c ỏnh s bi m l V(m). Bc 2: Do bc 1 nh v c ỏnh s l m, iu ny chng t ng i t u n v cú m cnh (cung) v l ng i ngn nht t u ti v. tỡm tt c cỏc ng i cú di m ngn nht t u ti v, ta xut phỏt t v i ngc v u theo nguyờn tc sau õy: - Tỡm tt c cỏc nh cú cnh (cung) ti b c ghi s m-1, gi s ú l x ik (k=1,2 ). - Vi mi nh x ik tỡm tt c cỏc nh cú cnh (cung) ti x ik c ghi s m-2. Bng cỏch lựi dn tr li, n mt lỳc no ú gp nh ghi s 0, ú chớnh l nh u. Tt c cỏc ng i xỏc inh theo cỏc bc trờn l ng i t u ti v vi di m ngn nht cn tỡm Vớ d Xột th cú hng cho bi hỡnh di õy (Hỡnh 6.1) Tỡm ng i ngn nht t nh v1 Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 61 Chu ý: Thuật toán tìm đường đi giữa hai đỉnh u và v trong đồ thị bằng cách áp dụng thuật toán tìm kiếm theo chiều rộng chính là đường đi ngắn nhất từ u tới v (theo số cạnh). 6.1.2 Tìm đường đi ngắn nhất trong đồ thị có trọng số Bài toán: Cho đồ thị có trọng số G = (V,E) và hai đỉnh s, t ∈V. Tìm đường đi ngắn nhất từ đỉnh s đến đỉnh t, tức là đường đi từ s đến t có tổng trọng số của các cạnh (cung) là nhỏ nhất. Phần lớn các thuật toán tìm đường đi ngắn nhất từ s đến t được xây dựn trên ý tưởng như sau: Từ ma trận trọng số c[u,v]; u,v ∈ V, ta tính cận trên d[v] của khoảng cách từ đỉnh s đến tất cả các đỉnh v ∈V, mỗi khi phát hiện d[u]+c[u,v]<d[v] thì cận trên d[v] sẽ được làm tốt lên: d[v]:=d[u]+c[u,v]. Quá trình đó sẽ kết thúc khi tất cả các cận trên d[v] không thể làm tốt lên được nữa. Khi thực hiện cài đặt trên máy tính, cận trên d[v] được gọi là nhãn của đỉnh v (hay trọng số của đỉnh v), còn việc làm tốt các cận trên d[v] được gọi là phép gán nhãn cho các đỉnh của đồ thị. Thuật toán có thể được mô ta như sau: Bước 1: Đánh trọng số các đỉnh. Trọng số của đỉnh xuất phát s được đánh trọng số (gán nhãn) d[s] = 0 Tại các đỉnh còn lại ta ghi một số dương đủ lớn sao cho nó lớn hơn trọng số của các đỉnh từ a tới (có thể dùng ∞) Bước 2: Thực hiện giảm trọng số các đỉnh Giả sử tại đỉnh v đang được ghi trọng số d[v]. N ếu tồn tại đỉnh u có trọng số d[u], từ u sang v mà d[v]>d[u] +c[u,v] thì ta thay trọng số d[v] bởi d’[v]=d[u]+c[u,v]. Trường hợp ngược lại ta giữ nguyên là d[v]. Quá trình thực hiện cho tới khi trọng số của tất cả các đỉnh đã đạt cực tiểu, tức là ∈∀v V không tồn tại u∈V kề với v mà d[u]+c[u,v]<d[v] . Bước 3: Xác định đường đi từ s tới t có trọng số nhỏ nhất Từ bước 2 ta xác định được trọng số của đỉnh t, xuất phát từ t ta đi về đỉnh kề với t, chẳng hạn đó là đỉnh x có tính chất d[t] = d[x] + c[x,t], nếu không có đỉnh x như vậy thì ta đi về đỉnh kề với t có trọng số nhỏ nhất, cứ tiếp tục như vậy ta sẽ đi về đến đỉnh y mà đỉnh kề là s sao cho d[y]=d[s]+c[ s,y], với d[s]=0. Ví dụ Tuy nhiên, trên thực tế việc tìm đường đi ngắn nhất giữa hai đỉnh lại có rất nhiều trường hợp riêng biệt mà chưa có một thuật toán nào thực sự tối ưu được tất cả, chẳng hạn đồ thị có trọng số của cạnh là một số âm, hay đồ thị có chứa chu trình có trọng số âm Sau đây ta sẽ xét qua môt số trường hợp riêng. 6.1.2.1 Đường đi ngắn nhất xuất phát từ một đỉnh (Thuật toán Ford – Bellman) Thuật toán tìm đường đi ngắn nhất từ một đỉnh s đến tất cả các đỉnh còn lại của đồ thị được đưa ra bởi hai nhà bác học Ford và Bellman, thuật toán này làm việc trong trường hợp trọng số của các cạnh (cung) là tuỳ ý, nhưng giả thiết rằng trong đồ thị không có chu trình âm. Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 62 Procedure Ford_Bellman; (* Đầu vào: Đồ thị G = (V,E) với n đỉnh, s ∈V là đỉnh xuất phát, c[u,v] là ma trận trọng số; Đầu ra: Khoảng cách ngắn nhất từ s đến tất cả các đỉnh còn lại d[v], Truoc[v] ghi nhận đỉnh đi trước v trong đường đi ngắn nhất từ s đến v; Giả thiết: Đồ thị không có chu trình âm; *) Begin (* Khởi tạo *) For v ∈V do Begin d[v]:=c[s,v]; Truoc[v]:=s; End; d[s]:=0; For k:=1 to n-2 do For v ∈ V\{s} do For u ∈V do If d[v]>d[u]+c[u,v] then Begin d[v]:=d[u]+c[u,v]; Truoc[v]:=u; End; End; 6.1.2.2Tìm đường đi ngắn nhất trong đồ thị có trọng số không âm (thuật toán Dijkstra) Dijkstra đề nghị một thuật toán tìm đường đi ngắn nhất từ một đỉnh tới tất cả các đỉnh còn lại của đồ thị. Thuật toán Dijkstra được xây dựng dựa trên cơ sở gán cho các đỉnh các nhãn tạm thời. N hãn của mỗi đỉnh cho biết cận trên của độ dài đường đi ngắn nhất từ đỉnh xuất phát đến nó. Các nhãn này sẽ được biến đổi theo các bước lặp, trong mỗi bước lặp có một nhãn tạm thời trở thành nhãn cố định. N ếu nhãn của một đỉnh nào đó trở thành cố định thì nó sẽ cho ta độ dài của đường đi ngắn nhất từ đỉnh xuất phát đến nó. Thuật toán được mô tả cụ thể như sau: Procedure Dijkstra; (* Đầu vào: Đồ thị G=(V,E) với n đỉnh cho bởi ma trận trọng số c[i,j] s ∈V là đỉnh xuất phát Đầu ra: Khoảng cách từ đỉnh s đến tất cả các đỉnh v còn lại là d[v] Truoc[v] ghi nhận đỉnh đi trước v trong đường đi ngắn nhất từ s đến v Giả thiết: Trọng số các cạnh (cung) của đồ thị là không âm *) Begin (* Khởi tao *) For v ∈V do Begin d[v]:=c[s,v]; Truoc[v]:=s; End; Gi¸o ¸n m«n: Lý ThuyÕt §å ThÞ NguyÔn Minh §øc - §HQG Hµ Néi 63 d[s]:=0; T:=V\{s}; (* T là tập các đỉnh có nhãn tạm thời *) (* Bước lặp *) While T φ ≠ do Begin Tìm đỉnh u thuộc T thoả mãn: d[u] = min{d[z]; z thuộc T}; T:=T\{u}; (* Cố định nhãn của đỉnh u *) for v thuộc T do (*Gán lại nhãn cho các đỉnh *) if d[v]>d[u] + c[u,v] then Begin d[v]:=d[u]+c[u,v]; Truoc[v]:=u; End; End; End; Ví dụ: . Giáo án môn: Lý Thuyết Đồ Thị Nguyễn Minh Đức - ĐHQG Hà Nội 60 v1 v2 v10 v5 v8 v9 v6 v7 v3 v4 Chng 6 MT S BI TON NG DNG (Bi toỏn tỡm ng i ngn nht v bi toỏn lung cc i) 6. 1 Bi toỏn. trong đồ thị bằng cách áp dụng thuật toán tìm kiếm theo chiều rộng chính là đường đi ngắn nhất từ u tới v (theo số cạnh). 6. 1.2 Tìm đường đi ngắn nhất trong đồ thị có trọng số Bài toán: Cho đồ. ưu được tất cả, chẳng hạn đồ thị có trọng số của cạnh là một số âm, hay đồ thị có chứa chu trình có trọng số âm Sau đây ta sẽ xét qua môt số trường hợp riêng. 6. 1.2.1 Đường đi ngắn nhất