1. Trang chủ
  2. » Luận Văn - Báo Cáo

Các thuật toán tìm đường đi ngắn nhất trong đồ thị lý thuyết, thuật toán và ứng dụng

74 971 0

Đ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

Thông tin cơ bản

Định dạng
Số trang 74
Dung lượng 11,04 MB

Nội dung

Đồ thị có trọng số trên các cạnh có thể sử dụng để giải các bài toán như : tìm đường đi ngắn nhất giữa hai thành phố trong cùng một mạng giao thông.. Khi đó ta thu được đồ thị có hướng l

Trang 1

MỤC LỤC

LỜI NÓI ĐẦU 1

Chương I: MỘT SỐ KIẾN THỨC CƠ BẢN TRONG LÝ THUYẾT ĐỒ THỊ 2

1.1 Các khái niệm cơ bản của lý thuyết đồ thị 2

1.1.1 Định nghĩa đồ thị 2

1.1.2 Các thuật ngữ cơ bản 5

1.1.3 Định nghĩa đường đi, chu trình, đồ thị liên thông 7

1.2 Đường đi ngắn nhất 11

1.2.1 Đường đi ngắn nhất xuất phát từ một đỉnh 11

1.2.2 Đường trong đồ thị không có chu trình 11

1.2.3 Đường đi ngắn nhất giữa hai cặp đỉnh 14

1.3 Một số bài toán dẫn đến bài toán tìm đường đi ngắn nhất trong đồ thị 15

1.3.1 Tìm đường đi ngắn nhất từ điểm A đến điểm B trong thành phố 15

1.3.2 Tối ưu hệ thống mạng truyền dẫn 18

Chương II: ĐƯỜNG ĐI NGẮN NHẤT TỪ MỘT ĐỈNH 21

2.1.Thuật toán Bellman-Ford 27

2.2 Thuật toán Dijkstra 31

2.3 Thuật toán tìm kiếm A* 37

Chương III : ĐƯỜNG ĐI NGẮN NHẤT GIỮA TẤT CẢ CÁC CẶP ĐỈNH 40

3.1 Thuật toán Floyd-Warshall 48

3.2 Thuật toán Johnson 55

Chương IV: ỨNG DỤNG THUẬT TOÁN TÌM ĐƯỜNG ĐI NGẮN NHẤT VÀO MÔ HÌNH HỆ THỐNG ROUTING TĨNH 60

4.1 Nguyên lý hoạt động cơ bản của Router trong hệ thống mạng 60

4.2 Ứng dụng một thuật toán (Dijkstra) 69

4.3 Thiết kế chương trình áp dụng thuật toán (Floyd-Warshall) 71

4.4 Kết quả thử nghiệm 71

TÀI LIỆU THAM KHẢO 73

Trang 2

LỜI NÓI ĐẦU

Lý thuyết đồ thị là một lĩnh vực nghiên cứu đã có từ lâu đời và có nhiều ứng dụng hiện đại.Những tư tưởng cơ bản của lý thuyết đồ thị đươc đề xuất từ 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

Đồ thị được sử dụng để giải quyết các bài toán trong nhiều lĩnh vực khác nhau Chẳng hạn, đồ thị có thể sử dụng để xác định các mạch vòng trong vấn đề giải tích mạch điện Chúng ta có thể phân biệt các hợp chất hoá học hữu cơ khác nhau với cùng công thức phân tử nhưng khác nhau về cấu trúc phân tử nhờ đồ thị Chúng ta

có thể xác định xem hai máy tính trong mạng có thể trao đổi thông tin được với nhau hay không nhờ mô hình đồ thị của mạng máy tính Đồ thị có trọng số trên các cạnh có thể sử dụng để giải các bài toán như : tìm đường đi ngắn nhất giữa hai thành phố trong cùng một mạng giao thông Chúng ta còn sử dụng đồ thị để giải các bài toán về lập lịch, thời khoá biểu và phân bố tần số cho các trạm phát thanh và truyền hình

Trong đời sống, chúng ta thường gặp các tình huống như sau: để đi từ điểm A đến điểm B trong thành phố, có nhiều đường đi, nhiều cách đi; có lúc ta chọn đường

đi ngắn nhất (theo nghĩa cự ly), có lúc lại cần trọn đường đi nhanh nhất (theo nghĩa thời gian),v.v…

Mục đích đề tài tìm hiểu, nghiên cứu các thuật toán tìm đường đi ngắn nhất trong đồ thị phục vụ việc nghiên cứu khoa học và ứng dụng vào thực tiễn

Củng cố và rèn luyện kỹ năng lập trình, nhớ lại các thuật toán

Chương I : Một số kiến thức cơ bản trong lý thuyết đồ thị

Chương III : Đường đi ngắn nhất giữa tất cả các cặp đỉnh

hệ thống routing tĩnh

Trang 3

Chương I: MỘT SỐ KIẾN THỨC CƠ BẢN TRONG LÝ

Định nghĩa 1 Đơn đồ thị vô hướng G=(V,E) bao gồm V là tập đỉnh và E là tập các

cặp không có thứ tự gồm hai phần tử khác nhau của V gọi là các cạnh

Trong trường hợp giữa hai máy tính nào đó thường xuyên phải truyền tải nhiều thông tin người ta phải nối hai máy này bởi nhiều kênh thoại Mạng với đa kênh thoại giữa các máy tính được cho trong hình 1.2

Trang 4

Hình 1.2 Sơ đồ mạng máy tính với đa kênh thoại

Định nghĩa 2 Đa đồ thị vô hướng G=(V,E) bao gồm V là tập các đỉnh, và E là họ

các cặp không có thứ tự gồm hai phần tử khác nhau của V gọi là các cạnh Hai

Hình 1.3 Sơ đồ mạng máy tính với kênh thông báo

Rõ ràng mỗi đơn đồ thị đều là đa đồ thị, nhưng không phải đa đồ thị nào cũng là đơn đồ thị, vì trong đa đồ thị có hai hay nhiều hơn cạnh nối một cặp đỉnh nào đó Trong mạng máy tính có thể có những kênh thoại nối một máy tính nào đó với chính nó Mạng như vậy được cho trong hình 1.3 Như vậy đa đồ thị không thể mô

Hà Nội

Đồng Nai

Hà Tây

Trang 5

tả được mạng như vậy, bởi vì có những khuyên (cạnh nối một đỉnh vói chính nó) Trong trường hợp này chúng ta cần sử dụng đến khái niệm giả đồ thị vô hướng, được định nghĩa như sau:

Định nghĩa 3 Giả đồ thị vô hướng G=(V,E) bao gồm V là tập các đỉnh, và E là họ

các cặp không có thứ tự gồm hai phần tử (không nhất thiết phải khác nhau) của V gọi là các cạnh Cạnh e được gọi là khuyến nếu có dạng e=(u,u)

Các kênh thoại trong mạng máy tính có thể chỉ cho phép truyền tin theo một chiều Chẳng hạn trong hình 1.4 máy chủ ở Hà Nội chỉ có thể nhận tin từ các máy ở địa phương, có một số máy chỉ có thể gửi tin đi, còn các kênh thoại cho phép truyền tin theo cả hai chiều được thay thế bởi hai cạnh có hướng ngược chiều nhau

Hà Tây Đồng Nai Huế An Giang

Hà Nội TPHCM Bình Định

Hình 1.4 Mạng máy tính với các kênh thoại một chiều

Định nghĩa 4 Đơn đồ thị có hướng G=(V,E) bao gồm V là tập các đỉnh, và E là tập

các cặp có thứ tự gồm hai phần tử khác nhau của V gọi là các cung

Nếu trong mạng có thể có đa kênh thoại một chiều, ta sẽ phải sử dụng đến khái

niệm đa đồ thị có hướng:

Định nghĩa 5 Đa đồ thị có hướng G=(V,E) bao gồm V là tập các đỉnh,và E là họ

Trong các phần tiếp theo chủ yếu chúng ta sẽ làm việc với đơn đồ thị vô hướng và đơn đồ thị có hướng Vì vậy, để cho ngắn gọn, ta sẽ bỏ qua tính từ đơn mỗi khi nhắc đến chúng

Trang 6

1.1.2 Các thuật ngữ cơ bản

Trong mục này chúng ta sẽ trình bày một số thuật ngữ cơ bản của lý thuyết đồ thị Trước tiên, ta xét các thuật ngữ mô tả các đỉnh và cạnh của đồ thị vô hướng

Định nghĩa 1 Hai đỉnh u và v của đồ thị có hướng G được gọi là kề nhau nếu (u,v)

là cạnh của đồ thị G Nếu e=(u,v) là cạnh của đồ thị thì ta nói cạnh này là cạnh liên thuộc với hai đỉnh u và v, hoặc cũng nói là cạnh e nối đỉnh u và đỉnh v, đồng thời các đỉnh u và v sẽ được gọi là các đỉnh đầu của cạnh (u,v)

Để có thể biết có bao nhiêu cạnh liên thuộc với một đỉnh, ta đưa vào định nghĩa sau

Định nghĩa 2 Ta gọi bậc của đỉnh v trong đồ thị vô hướng là số cạnh liên thuộc

với nó ta sẽ kí hiệu là deg(v)

Chứng minh Rõ ràng trong mỗi cạnh e=(u,v) được tính một lần trong deg(u) và

một lần trong deg(v) Từ đó suy ra tổng tất cả các bậc của các đỉnh bằng hai lần số cạnh

Thí dụ 2 Đồ thị với n đỉnh và mỗi đỉnh có bậc là 6 có bao nhiêu cạnh ?

Giải: Theo định lý 1, ta có 2m=6n Từ đó suy ra số cạnh của đồ thị là 3n

Trang 7

Hệ quả Trong đồ thị vô hướng, số đỉnh bậc lẻ (nghĩa là có bậc là số lẻ) là một số

Ta xét các thuật ngữ tương tự cho đồ thị có hướng

Định nghĩa 3 Nếu e=(u,v) là cung của đồ thị có hướng G thì ta nói hai đỉnh u và v

là kề nhau, và nói cung(u,v) nối đỉnh u với đỉnh v hoặc cũng nói cung này là đi ra khỏi đỉnh u và đi vào đỉnh v Đinh u (v) sẽ được gọi là đỉnh đầu (cuối) của cung (u,v)

Tương tự như khái niệm bậc, đối với đồ thị có hướng ta có khái niệm bán bậc ra (vào) của một đỉnh

Định nghĩa 4 Ta gọi bán bậc ra (vào) của đỉnh v trong đồ thị có hướng là số cung

e d

Hình 1.6 Đồ thị có hướng G

Thí dụ 3 Xét đồ thị cho trong hình 1.6 Ta có

deg-(a)=1, deg-(b)=2, deg-(c)=2, deg-(d)=2, deg-(e)=2

deg+(a)=3, deg+(b)=1 deg+(c)=1, deg+(d)=2, deg+(e)=2

Do mỗi cung (u,v) sẽ được tính một lần trong bán bậc vào của đỉnh v và một lần trong bán bậc ra của đỉnh u nên ta có

Trang 8

Định lý 2 Giả sử G=(V,E) là đồ thị có hướng, khi đó

1.1.3 Định nghĩa đường đi, chu trình, đồ thị liên thông

Định nghĩa 1 Đường đi độ dài n từ đỉnh u đến đỉnh v, trong đó n là số nguyên

dương, trên đồ thị vô hướng G=(V,E) là dãy

x o , x 1 , , x n-1 , x n

trong đó u= x o , v= x n , (x i , x i+1 ) ∈ E , i=0,1,2, ,n-1

Đường đi nói trên còn có thể biểu diễn dưới dạng các cạnh:

(x o , x 1 ) , (x o , x 2 ), , (x n-1 , x n )

Đỉnh u gọi là đỉnh đầu, còn đỉnh v gọi là đỉnh cuối của đường đi Đường đi có đỉnh đầu trùng với đỉnh cuối (tức là u=v) được gọi là chu trình Đường đi hay chu trình được gọi là đơn nếu như không có cạnh nào bị lặp lại

Thí dụ 1 Trên đồ thị vô hướng cho trong hình 1.7: a,d,c,f,e là đường đi đơn độ dài

4 Còn d,e,c,a không là đường đi do (e,c) không phải là cạnh của đồ thị Dãy b,c,f,e,b là chu trình độ dài 4 Đường đi a,b,e,d,a,b có độ dài là 5 không phải là đường đi đơn, do cạnh (a,b) có mặt trong nó hai lần

d e f d e f

Hình 1.7 Đường đi trên đồ thị

Trang 9

Khái niệm đường đi và chu trình trên đồ thị có hướng được định nghĩa hoàn toàn tương tự như trường hợp đồ thị vô hướng, chỉ khác là ta chú ý đến hướng trên các cung

Định nghĩa 2 Đường đi độ dài n từ đỉnh u đến đỉnh v, trong đó n là số nguyên

dương, trên đồ thị có hướng G=(V,A) là dãy

độ dài 4 Còn d e c a không là đường đi do (e,c) không phải là cung của đồ thị Dãy b,c,f,e,b là chu trình độ dài 4 Đường đi a b e d a b có độ dài là

5 không phải là đường đi đơn, do cung (a,b) có mặt trong nó hai lần

Xét một mạng máy tính Một câu hỏi đặt ra là hai máy tính bất kỳ trong mạng này có thể trao đổi được thông tin với nhau hoặc trực tiếp qua kênh nối chúng hoặc thông qua một hoặc vài máy tính trung gian trong mạng ? Nếu sử dụng đồ thị để biểu diễn mạng máy tính này (trong đó các đỉnh của đồ thị tương ứng với các máy tính, còn các cạnh tương ứng với các kênh nối) câu hỏi đó được phát biểu trong ngôn ngữ đồ thị như sau: Tồn tại hay chăng đường đi giữa mọi cặp đỉnh của đồ thị ?

Định nghĩa 3 Đồ thị vô hướng G=(V,E) được gọi là liên thông nếu luôn tìm được

đường đi giữa hai đỉnh bất kỳ của nó

Như vậy hai máy tính bất kỳ trong mạng có thể trao đổi thông tin được với nhau khi

và chỉ khi đồ thị tương ứng với mạng này là đồ thị liên thông

Trang 10

Thí dụ 3 Trong hình 1.8: Đồ thị G là liên thông, đồ thị H là không liên thông

Định nghĩa 4 Ta gọi đồ thị con của đồ thị G=(V,E) là đồ thị H=(W,F), trong đó

W ⊆ V và F ⊆ E

Trong trường hợp đồ thị là không liên thông, nó sẽ rã ra thành một số đồ thị con liên thông đôi một không có đỉnh chung Những đồ thị con liên thông như vậy ta sẽ gọi là các thành phần liên thông của đồ thị

Thí dụ 4 Đồ thị H trong hình 1.8 gồm 3 thành phần liên thông là H 1 ,H 2 ,H 3.

Trong mạng máy tính có thể có những máy (những kênh nối) mà sự hỏng hóc của

nó có thể ảnh hưởng đến việc trao đổi thông tin trong mạng Các khái niệm tương ứng với tình huống này được đưa ra trong định nghĩa sau

Định nghĩa 5 Đỉnh v được gọi là đỉnh rẽ nhánh nếu việc loại bỏ v cùng với các

cạnh liên thuộc với nó khỏi đồ thị làm tăng số thành phần liên thông của đồ thị Cạnh e được gọi là cầu nếu việc loại bỏ nó khỏi đồ thị làm tăng số thành phần liên thông của đồ thị

Thí dụ 5 Trong đồ thị G ở hình 2, đỉnh d và e là đỉnh rẽ nhánh, còn các cạnh (d,g)

và (e,f) là cầu

Đối với đồ thị có hướng có hai khái niệm liên thông phụ thuộc vào việc ta có xét đến hướng trên các cung hay không

Định nghĩa 6 Đồ thị có hướng G=(V,A) được gọi là liên thông mạnh nếu luôn tìm

được đường đi giữa hai đỉnh bất kỳ của nó

Trang 11

Định nghĩa 7 Đồ thị có hướng G=(V,A) được gọi là liên thông yếu nếu đồ thị vô

hướng tương ứng với nó là đồ thị vô hướng liên thông

Rõ ràng nếu đồ thị là liên thông mạnh thì nó cũng là liên thông yếu, nhưng điều ngược lại là không luôn đúng, như chỉ ra trong thí dụ dưới đây

Thí dụ 6 Trong hình 1.9 đồ thị G là liên thông mạnh, còn H là liên thông yếu

nhưng không là liên thông mạnh

Hình 1.9 Đồ thị liên thông mạnh G và đồ thị liên thông yếu H

Một câu hỏi đặt ra là khi nào có thể định hướng các cạnh của một đồ thị vô hướng liên thông để có thể thu được một đồ thị có hướng liên thông mạnh? Ta sẽ gọi đồ thị như vậy là đồ thị định hướng được Định lý dưới đây cho ta tiêu chuẩn nhận biết một đồ thị có là định hướng được hay không

Định lý 1 Đồ thị vô hướng liên thông là định hướng được khi và chỉ khi mỗi cạnh

của nó nằm trên ít nhất một chu trình

Chứng minh Điều kiện cần Giả sử (u,v) là một cạnh của đồ thị, từ sự tồn tại

đường đi có hướng từ u đến v và ngược lại suy ra (u,v) phải nằm trên ít nhất một chu trình

Điều kiện đủ Thủ tục sau đây cho phép định hướng các cạnh của đồ thị để thu

được đồ thị có hướng liên thông mạnh Giả sử C là một chu trình nào đó trong đồ thị Định hướng các cạnh trên chu trình này theo một hướng đi vòng theo nó Nếu tất các cạnh của đồ thị là đã được định hướng thì kết thúc thủ tục Ngược lại, chọn C

là một cạnh chưa định hướng có chung đỉnh với ít nhất một trong số các cạnh đã định hướng Theo giả thiết tìm được chu trình C chứa cạnh e Định hướng các cạnh

Trang 12

chưa được định hướng của C’ theo một hướng dọc theo chu trình này (không định hướng lại các cạnh đã có hướng) Thủ tục trên sẽ được lặp lại cho đến khi tất cả các cạnh của đồ thị được định hướng Khi đó ta thu được đồ thị có hướng liên thông mạnh

1.2 Đường đi ngắn nhất

1.2.1 Đường đi ngắn nhất xuất phát từ một đỉnh

Phần lớn các thuật toán tìm khoảng cách giữa hai đỉnh s và t được xây dựng nhờ kỹ thuật tính toán mà ta có thể mô tả như sau: từ ma trận trọng số a[u,v],u,v V,

ta tính cận trên d[v] của khoảng cách từ s đến tất cả các đỉnh v V Mỗi khi phát hiện

d[u]+a[u,v]<d[v] (1) cận trên d[v] sẽ được tốt lên : d[v]=d[u]+a[u,v]

Quá trình đó sẽ kết thúc khi nào chúng ta không làm tốt thêm được bất cứ cận trên nào Khi đó, rõ ràng giá trị của mỗi d[v] sẽ cho ta khoảng cách từ mỗi đỉnh s đến v Khi thể hiện kỹ thuật tính toán này trên máy tính, cận trên d[v] sẽ được gọi là nhãn của đỉnh v, còn việc tính lại các cận trên này sẽ gọi là phép gán nhãn cho đồ thị và toàn bộ thủ tục thường gọi là thủ tục gán nhãn

Sơ đồ tính toán mà ta vừa mô tả còn chưa là xác định, bởi vì còn phải chỉ ra thứ tự chọn các đỉnh u và v để kiểm tra điều kiện (1) Thứ tự chọn này có ảnh hưởng rất lớn đến hiệu quả thuật toán

1.2.2 Đường trong đồ thị không có chu trình

Bây giờ ta xét trường hợp riêng thứ hai của bài toán tìm đường đi ngắn nhất,

mà để giải nó có thể xây dựng thuật toán với độ phức tạp tính toán O( ), đó là đồ thị không có chu trình (còn trọng số trên các cung có thể là các số thực tuỳ ý) Trước hết ta chứng minh định lý sau

Định lý 2 Giả sử G là đồ thị không có chu trình Khi đó các đỉnh của nó có thể

đánh số sao cho mỗi cung của đồ thị chỉ hướng từ đỉnh có chỉ số nhỏ hơn đến đỉnh

Trang 13

có chỉ số lớn hơn, nghĩa là mỗi cung của nó có thể biểu diễn dưới dạng (v[i],v[j]), trong đó i<j

Thí dụ 3 Đồ thị trong hình 1.10 có các đỉnh được đánh số thỏa mãn điều kiện nêu

(* Đầu vào: Đồ thị có hướng G=(V,E) với n đỉnh không chứa chu trình được

cho bởi danh sách kề Ke(v),v V

Đầu ra: Với mỗi đỉnh v V chỉ số NR[u] < NR[v] *)

Trang 14

Thuật toán được xây dựng dựa trên ý tưởng rất đơn giản sau: Rõ ràng trong

đồ thị không có chu trình bao giờ cũng tìm được đỉnh có bán bậc vào bằng 0 (không

có cung đi vào) Thực vậy, bắt đầu từ đỉnh v1 nếu có cung đi vào nó từ v2 thì ta lại chuyển sang xét đỉnh v2 Nếu có cung v3 đi vào v2, thì ta chuyển sang xét v3 Do

đồ thị là không có chu trình nên sau một số hữu hạn lần chuyển như vậy ta phải đi đến đỉnh không có cung đi vào Đầu tiên, tìm các đỉnh như vậy của đồ thị Rõ ràng

ta có thể đánh số chúng theo một thứ tự tuỳ ý bắt đầu từ 1 Tiếp theo, loại bỏ khỏi

đồ thị những đỉnh đã được đánh số cùng các cung đi ra khỏi chúng, ta thu được đồ thị mới cũng không có chu trình, và thủ tục được lặp lại với đồ thị mới này Quá trình đó sẽ được tiếp tục cho đến khi tất cả các đỉnh của đồ thị được đánh số

sẽ phải duyệt qua tất cả các cung này Suy ra để đánh số tất cả các đỉnh của

đồ thị chúng ta sẽ phải duyệt tất cả các cung của đồ thị một lần nữa Vậy độ phức tạp thuật toán là O(m)

2 Thuật toán có thể để kiểm tra xem đồ thị có chứa chu trình hay không? Thực vậy, nếu kết thúc thuật toán vẫn còn có đỉnh chưa được đánh số (num<n) thì điều đó có nghĩa là đồ thị chứa chu trình

Do có thuật toán đánh số trên, nên khi xét đồ thị không có chu trình ta có thể giả thiết là các đỉnh của nó được đánh số sao cho mỗi cung chỉ đi từ đỉnh có chỉ số nhỏ đến đỉnh có chỉ số lớn hơn Thuật toán tìm đường đi ngắn nhất trên đồ thị không có chu trình được mô tả trong sơ đồ sau đây:

Procedure Critical_Path;

(* Tìm đường đi ngắn nhất từ đỉnh nguồn đến tất cả các đỉnh còn lại trên đồ thị không có chu trình *)

Đầu vào: Đồ thị G=(V,E) trong đó V= { v[1], v[2], , v[n] }

Trang 15

Đồ thị được cho bởi danh sách kề Ke(v),vV

Đầu ra: Khoảng cách từ v[1] đến tất cả các đỉnh còn lại được ghi trong

Các thuật toán mô tả ở trên thường được ứng dụng vào việc xây dựng những

phương pháp giải bài toán điều khiển việc thực hiện những dự án lớn, gọi tắt là

PERT (Project Evaluation and Review Technique) hay CMD ( Critical path

method)

1.2.3 Đường đi ngắn nhất giữa hai cặp đỉnh

Rõ ràng ta có thể giải bài toán tìm đường đi ngắn nhất giữa tất cả các cặp đỉnh

của đồ thị bằng cách sử dụng n lần thuật toán mô tả ở mục trước, trong đó ta sẽ

chọn s lần lượt là các đỉnh của đồ thị Rõ ràng, khi đó ta thu được thuật toán với độ

phức tạp là O(n4) (nếu dùng thuật toán Ford-Bellman) hoặc O(n3) đối với trường

hợp trọng số 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(n3) : thuật toán Floyd, thuật toán đượ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

Trang 16

Ma trận ghi nhận đường đi

d[i,j]:=a[i,j];

p[i,j]:=i;

end;(* Bước lặp *) For k:=1 to n do

Rõ ràng độ phức tạp của thuật toán là O(n3)

1.3 Một số bài toán dẫn đến bài toán tìm đường đi ngắn nhất trong đồ thị 1.3.1 Tìm đường đi ngắn nhất từ điểm A đến điểm B trong thành phố

Trong đời sống, chúng ta thường gặp những tình huống như sau: để đi từ địa điểm A đến địa điểm B trong thành phố, có nhiều đường đi, nhiều cách đi; có lúc ta chọn đường đi ngắn nhất (theo nghĩa cự ly), có lúc lại cần chọn đường đi nhanh nhất (theo nghĩa thời gian) và có lúc phải cân nhắc để chọn đường đi rẻ tiền nhất (theo nghĩa chi phí), v.v

Có thể coi sơ đồ của đường đi từ A đến B trong thành phố là một đồ thị, với đỉnh là các giao lộ (A và B coi như giao lộ), cạnh là đoạn đường nối hai giao lộ

Trang 17

Trên mỗi cạnh của đồ thị này, ta gán một số dương, ứng với chiều dài của đoạn đường, thời gian đi đoạn đường hoặc cước phí vận chuyển trên đoạn đường đó,

Đồ thị có trọng số là đồ thị G=(V,E) mà mỗi cạnh (hoặc cung) được gán một giá trị (nguyên hoặc thực) gọi là trọng số ứng với cạnh (hoặc cung) đó

Có thể xem một đồ thị G bất kỳ là một đồ thị có trọng số mà mọi cạnh đều có chiều dài 1 Khi đó, khoảng cách d(u,v) giữa hai đỉnh u và v là chiều dài của đường

đi từ u đến v ngắn nhất, tức là đường đi qua ít cạnh nhất

Bài toán tìm đường đi ngắn nhất

Cho đơn đồ thị liên thông, có trọng số G=(V,E) Tìm khoảng cách d(s,f) từ một đỉnh s cho trước đến một đỉnh f bất kỳ của G và tìm đường đi ngắn nhất từ s đến f Nếu như đồ thị có chu trình âm (chu trình với độ dài âm) thì khoảng cách giữa một số cặp đỉnh nào đó có thể không xác định Trong trường hợp này có thể tìm đường đi cơ bản ngắn nhất

Nếu như đồ thị không có chu trình âm thì ta có thể chứng minh được rằng một trong những đường đi ngắn nhất là đường đi cơ bản Việc tìm đường đi ngắn nhất giữa 2 đỉnh s và f có thể áp dụng thuật toán sau:

Gọi a[u,v] là trọng số của cạnh (u,v) Qui ước a[v,v]=0 với ∀vV Đặt d[s,v] là khoảng cánh từ s tới v Để tìm đường đi từ s tới f ta nhận thấy rằng luôn tồn tại f1≠ f sao cho d[s,f]=d[s,f1]+a[f1,f]

Đỉnh f1 đó là đỉnh liền trước trong đường đi từ s tới f Nếu f1≡ s thì kết thúc trái lại ta tìm đỉnh f2 sao cho d[s,f1]=d[s,f2]+a[f2,f] Cứ tiếp tục như vậy sau hữu hạn bước ta xác đinh được đường đi ngắn nhất từ s tới f

Áp dụng thuật toán Ford-Bellman

Bước 1: Khởi tao xuất phát từ đỉnh s Gọi d[v] là khoảng cánh từ s tới v khởi tạo d[s]=0; d[v]:=a[s,v]

Bước 2: Lặp

2.1 Tối ưu hóa dần d[v] như sau: Xét mọi cặp đỉnh (u,v) của đồ thị nếu d[v]>d[u]+a[u,v] thì đặt d[v]=d[u]+a[u,v] và t[v]=u (mảng t lưu vết đường đi)

Trang 18

2.2 Bước lặp kết thúc khi không thể tối ưu thêm bất kì một nhãn d[v] nào nữa, dùng biến stop để kiểm soát quá trình này

Procedure Ford_Bellman;

Begin

for for (v V) do begin d[v]:=a[s,v]; t[v]:=s; end;

d[s]:=0;

repeat

stop:=true;

for (u V) do for (v V) and (u,v) E do

if d[v]>d[u]+ a[u,v] then begin

Ví dụ: Cho đồ thi G=(V,E) Tìm đường đi ngắn nhất từ đỉnh A đến F

Ta kí hiệu t[v] là đỉnh trước của v trên đường đi từ A tới F Minh họa kết quả tính toán của thuật toán Ford-bellman qua bảng sau:

Bước d[a],t[a] d[b],t[b] d[c],t[c] d[d],t[d] d[e],t[e] d[f],t[f]

Trang 19

1.3.2 Tối ưu hệ thống mạng truyền dẫn

Bài toán tìm đường đi ngắn nhất là một bài toán khá quan trọng trong quá trình thiết kế và phân tích mạng Hầu hết các bài toán định tuyến có thể giải quyết như giải quyết bài toán tìm đường đi ngắn nhất khi một “độ dài” thích hợp được gắn vào mỗi cạnh (hoặc cung) trong mạng Trong khi các thuật toán thiết kế thì cố gắng tìm kiếm cách tạo ra các mạng thỏa mãn tiêu chẩn độ dài đường đi

Ta xét các graph hữu hướng và giả sử rằng đã biết độ dài của một cung giữa mỗi cặp nút i và j là lij Các độ dài này không cần phải đối xứng Khi một cung không tồn tại thì độ dài lij được giả sử là rất lớn (chẳng hạn lớn gấp n lần độ dài cung lớn nhất trong mạng) Chú ý rằng có thể áp dụng quá trình này cho các mạng

vô hướng bằng cách thay mỗi cạnh bằng hai cung có cùng độ dài Ban đầu giả sử rằng lij là dương hoàn toàn; sau đó giả thiết này có thể được thay đổi

Phần lớn các mạng chuyển mạch gói sử dụng các thuật toán khác nhau của phương pháp chọn tuyến đường ngắn nhất do lớp mạng thực hiện Một số mạng chọn tuyến theo cách thức tập trung, thiết lập đường dẫn giữa nút nguồn và nút đích

ở trung tâm điều hành mạng NMC (Network Management Center) hay trung tâm điều khiển chọn tuyến RCC (Routing Control Center) rồi sau đó phân phối các thông tin chọn tuyến đến tất cả các nút chuyển mạch trong mạng Các nút mạng khác sử dụng cách thức phi tập trung hay còn gọi là cách thức phân bố, từng nút trao đổi thông tin chọn tuyến và giá thành với các nút khác trong mạng trên cơ sở tương tác cho đến khi các bảng định tuyến đáp ứng được yêu cầu định tuyến ngắn nhất

Xét mạng như hình 1.11, trên mỗi đường ghép nối có các trọng số tương ứng với giá thành của từng đường, để đơn giản ta coi các trọng số này theo cả hai chiều

là như nhau, mặc dù trên thực tế chúng có thể khác nhau về giá trị Để chọn được đường dẫn ngắn nhất từ một nguồn tới tất cả các nút trong mạng, đòi hỏi phải có kiến thức về cấu hình tổng thể của mạng (danh sách các nút và các ghép nối giữa chúng) cũng như giá thành của từng đường nối Điều đó dẫn tới việc tính toán tập

Trang 20

trung dựa trên thông tin đầy đủ lưu trong các cơ sở dữ liệu trung tâm (Central Database)

Hình 1.11 Mô hình một mạng

Thuật toán được thực hiện theo từng bước, xây dựng mô hình cây đường ngắn nhất (Shortest Path Tree) có gốc tại nút nguồn (nút 1) Các đường dẫn ngắn nhất tới

k nút khác được tính toán trong k bước, chúng được tập hợp lại trong tập N

Coi D(v) là khoảng cách (tổng của các trọng số đường nối dọc theo đường dẫn) từ nút nguồn 1 tới nút v Coi l(i,j) là giá thành đã cho giữa 2 nút i và j Thuật toán gồm 2 bước:

1.Bước khởi đầu

Đặt N={1} (tập N ban đầu chỉ gồm duy nhất 1 nút), với mỗi nút v  N đặt D(v)=l(l,v), với các nút không nối trực tiếp với nút l ta coi giá thành bằng 

2.Bước lặp

Tìm nút w không thuộc N sao cho D(w) là tối thiểu và bổ sung w vào tập N Sau đó thay D(v) cho toàn bộ các nút không thuộc N còn lại bằng cách tính:

D(v)min[D(v),D(w) + l(w,v)]

Bước này được lặp lại cho đến khi tất cả các nút đều có trong N

Sau khi thực hiện, ta lần lượt có được các bước mô tả bởi bảng thống kê sau:

Trang 22

phương thức phân bố thì từng nút phải tính lấy bảng định tuyến, cùng sử dụng các thông tin tổng thể như trên (được cung cấp bởi các nút lân cận hoặc bởi NMC) và chọn ra cây đường dẫn cho riêng nó

Chương II: ĐƯỜNG ĐI NGẮN NHẤT TỪ MỘT ĐỈNH

Một người lái xe muốn tìm một đường đi ngắn nhất có thể từ Hà Nội đến Hải Dương Từ một bản đồ các tuyến đường của Việt Nam trên đó khoảng cách giữa các ngã đường kề nhau cho trước, làm thế nào chúng ta có thể xác định được đường đi ngắn nhất này

Một cách có thể là liệt kê tất cả các tuyến đường từ Hà Nội đến Hải Dương, tính độ dài đường đi trên mỗi tuyến đường, và chọn đường đi ngắn nhất Dễ thấy rằng, mặc dù chúng ta không kể đến những đường đi có chứa chu trình, vẫn có hàng triệu khả năng có thể, hầu hết trong chúng là những đường đi không đáng để chúng

ta xem xét Ví dụ, một đường đi từ Hà Nội qua Sài Gòn đến Hải Dương là một lựa chọn tồi vì Sài Gòn ở cách xa đường đi ngắn nhất đến hàng nghìn dặm

Trong chương này chúng ta sẽ chỉ ra làm thế nào để giải quyết những bài toán như vậy một cách hiệu quả Trong một bài toán tìm đường đi ngắn nhất, chúng ta

được cho trước một đồ thị định hướng có trọng số G = (V,E), với hàm trọng số w :

ER ánh xạ các cạnh của đồ thị vào tập các số thực Trọng số của một đường đi

w

1

1 , ) ( )

(

Chúng ta định nghĩa trọng số đường đi ngắn nhất từ một đỉnh u đến một đỉnh v như sau:

Một đường đi ngắn nhất từ một đỉnh u đến một đỉnh v được định nghĩa là một

đường đi bất kì p mà có w(p) = (u,v)

Trang 23

Các biến thể

Trong chương này, chúng ta sẽ tập trung vào bài toán tìm đường đi ngắn nhất

từ một đỉnh: cho trước một đồ thị G = (V,E), chúng ta muốn tìm một đường đi ngắn nhất từ một đỉnh nguồn cho trước s  V đến mỗi đỉnh v  V Có rất nhiều bài toán

có thể giải được bằng thuật toán cho bài toán tìm đường đi ngắn nhất từ một đỉnh, trong đó có các biến thể sau đây:

- Tìm đường đi ngắn nhất đến một đỉnh

- Tìm đường đi ngắn nhất giữa một cặp

- Tìm đường đi ngắn nhất giữa tất cả các cặp

Bổ đề (Đoạn con của đường đi ngắn nhất là một đường đi ngắn nhất)

mãn 1 i j k, ta có p ij = <v i , v i+1 , , v j > là một đường đi ngắn nhất từ v i đến v j

v v v v , khi đó ta có w(p) = w(p1i) + w(pij) + w(pjk) Giả sử có một đường đi ngắn nhất p’ij từ vi đến vj với trọng số w(p’ij) <w(pij) Khi đó 1 '

1

ij jk

i p p p

Trang 24

nhỏ hơn luôn có thể được tìm thấy bằng cách cộng thêm vào đường đi đó chu trình với trọng số âm đã nói Nếu có một chu trình trọng số âm trên một đường đi nào đó

 Vì g có thể tới được từ f, chúng ta có thể tìm đường đi với trọng số âm lớn tuỳ ý

từ s đến g, và (s,g) = -  Các đỉnh h, i và j cũng tạo thành một chu trình với trọng

số âm, nhưng chúng không đến được từ s, do vậy (s,h) = (s,i) = (s,j) = 

Hình 2.1 Các trọng số cạnh âm trong một đồ thị định hướng Ghi bên trong các

đỉnh là trọng số đường đi ngắn nhất của nó từ nguồn s Vì các đỉnh e và f tạo thành một chu trình trọng số âm đến được từ s, chúng có trọng số đường đi nhỏ nhất bằng - Vì đỉnh g đến được từ một đỉnh có trọng số đường đi ngắn nhất là -, nó cũng

Trang 25

có trọng số đường đi ngắn nhất là - Các đỉnh như h, i và j không đến được từ s, nên trọng số đường đi ngắn nhất của chúng là , mặc dù chúng nằm trên một chu trình trọng số âm

Chu trình

Một đường đi ngắn nhất có thể chứa một chu trình hay không? Như chúng ta vừa được biết, nó không thể chứa một chu trình trọng số âm Ta dễ dàng thấy là nó cũng không thể chứa một chu trình trọng số dương, vì nếu một đường đi chứa một chu trình trọng số dương, loại bỏ chu trình đó thì ta sẽ nhận được một đường đi có cùng đỉnh nguồn và đỉnh đích nhưng có trọng số nhỏ hơn đường đi ban đầu Nghĩa

là, nếu p = <v 0 , v 1 , , v k > là một đường đi và c = <v i , v i+1 , , v j > là một chu trình

trọng số dương, thì p’ = <v 0 , v 1 , , v i , v j+1 , v j+2 , , v k > có trọng số w(p’) = w(p) -

Chỉ còn lại các chu trình có trọng số bằng 0 Chúng ta có thể loại bỏ một chu trình có trọng số bằng 0 khỏi bất kì một đường đi nào chứa nó và đường đi nhận được sẽ có cùng một trọng số với đường đi ban đầu Theo cách đó, nếu có một

đường đi ngắn nhất từ một đỉnh nguồn s đến một đỉnh đích v chứa một chu trình có trọng số 0, tồn tại một đường đi ngắn nhất khác từ s đến v mà không chứa chu trình

này Chừng nào một đường đi ngắn nhất còn chứa những chu trình có trọng số 0, chúng ta có thể liên tiếp lặp lại việc loại bỏ những chu trình này ra khỏi đường đi cho đến khi chúng ta nhận được một đường đi ngắn nhất không chứa chu trình Do vậy, không mất tính chất tổng quát, chúng ta có thể giả sử rằng khi chúng ta tìm đường đi ngắn nhất, các đường đi mà chúng ta xét sẽ không có chu trình Do một

đường đi không có chu trình trong một đồ thị G = (V,E) chứa nhiều nhất là |V| đỉnh,

nó chứa nhiều nhất |V| - 1 cạnh Từ đó, chúng ta có thể giới hạn việc tìm kiếm của chúng ta trên những đường đi ngắn nhất có nhiều nhất |V| - 1 cạnh

Biểu diễn đường đi ngắn nhất

Cho trước một đồ thị G = (V,E), đối với mỗi đỉnh v, chúng ta lưu trữ một đỉnh

trước [v], có thể là một đỉnh khác v hoặc là NIL Thuật toán tìm đường đi ngắn

Trang 26

nhất trong chương này đặt các giá trị của  sao cho chuỗi các đỉnh trước bắt đầu từ

một đỉnh v chạy ngược trở lại theo đường đi ngắn nhất từ s đến v Từ đó, cho trước một đỉnh v với [v]  NIL, thủ tục PRINT-PATH(G,s,v)

Tuy nhiên, trong quá trình đang thực hiện một thuật toán tìm đường đi ngắn nhất, các giá trị của  không cần phải chỉ ra đường đi ngắn nhất Như trong tìm

kiếm theo chiều rộng, chúng ta sẽ quan tâm đến đồ thị con đỉnh trước G = (V, E)

sinh ra bởi các giá trị của  Ở đây, chúng ta lại định nghĩa tập đỉnh V là tập các

đỉnh của G với đỉnh trước khác NIL, và đỉnh s:

V = {vV: [v]  NIL}  {s}

Tập cạnh định hướng E là tập các cạnh sinh ra bởi các giá trị của  đối với

các đỉnh trong V

E = {([v],v) E: vV - {s}}

Chúng ta sẽ chứng minh rằng các giá trị  sinh ra bởi thuật toán trong chương

này có tính chất là sau khi kết thúc thuật toán, G sẽ là một cây đường đi ngắn nhất,

hiểu một cách không hình thức, là một cây chứa đường đi ngắn nhất từ s đến mỗi đỉnh có thể đến được từ s Để cho chính xác, giả sử G = (V,E) là một đồ thị định hướng có trọng số với hàm trọng số: w : ER, và giả sử rằng G không chứa các chu trình trọng số âm có thể đến được từ đỉnh nguồn sV, nghĩa là để cho các đường đi ngắn nhất hoàn toàn xác định Một cây đường đi ngắn nhất có gốc là s là một đồ thị định hướng G’ = (V’, E’) trong đó V’ V, E’ E, sao cho

Trang 27

Hình 2.2 (a) Một đồ thị định hướng có trọng số với các trọng số đường đi

ngắn nhất từ đỉnh nguồn s (b) Các cạnh tô đậm tạo thành một cây đường đi ngắn nhất có gốc là đỉnh nguồn s (c) Một đường đi ngắn nhất khác với cùng gốc

Phép giãn (Relaxing)

Thuật toán trong chương này sử dụng kĩ thuật giãn.Với một đỉnh vV, chúng

ta lưu trữ một thuộc tính d[v], là một chặn trên của trọng số đường đi ngắn nhất từ s đến v Chúng ta gọi d[v] là một đánh giá đường đi ngắn nhất.Chúng ta khởi động

các đánh giá đường đi ngắn nhất và đỉnh trước bằng thủ tục có độ phức tạp O(V) INITIALIZE-SINGLE-SOURCE(G,s)

Trang 28

Hình 2.3 Giãn một cạnh (u,v) với trọng số w(u,v) = 2 Đánh giá đường đi ngắn

nhất của mỗi đỉnh được ghi bên trong đỉnh.(a) Vì d[v] >d[u] + w(u,v) trước phép giãn, giá trị của d[v] giảm (b)ở đây, d[v] d[u] + w(u,v) trước phép giãn và do vậy

d[v] không thay đổi bởi phép giãn

RELAX(u,v,w)

1 Ifd[v] >d[u] + w(u,v)

2 then d[v] d[u] + w(u,v)

đó chúng giãn các cạnh Trong thuật toán Dijkstra và thuật toán tìm đường đi ngắn nhất cho đồ thị định hướng không có chu trình, mỗi cạnh được giãn đúng một lần Trong thuật toán Bellman-Ford, mỗi cạnh được giãn nhiều lần

2.1.Thuật toán Bellman-Ford

Thuật toán Bellman-Ford giải bài toán đường đi ngắn nhất từ một đỉnh cho

trường hợp tổng quát trong đó đồ thị có thể có các cạnh với trọng số âm Cho trước

một đồ thị định hướng, có trọng số G = (V,E) với một đỉnh nguồn s và một hàm trọng số w : E R, thuật toán Bellman-Ford trả về một giá trị bool chỉ ra rằng

trong đồ thị có tồn tại một chu trình với trọng số âm hay không Nếu có một chu

Trang 29

trình như vậy, thuật toán chỉ ra rằng bài toán không có nghiệm Nếu không có một chu trình như vậy, thuật toán cho ra các đường đi ngắn nhất và trọng số của chúng Thuật toán sử dụng các phép giãn, giảm dần một đánh giá trọng số đường đi

ngắn nhất d[v] từ đỉnh nguồn s đến mỗi đỉnh v  V cho đến khi nó đạt đến trọng số

đường đi ngắn nhất thực sự (s,v) Thuật toán trả về giá trị TRUE nếu và chỉ nếu đồ thị không chứa các chu trình với trọng số âm có thể đến được từ đỉnh s

5 for mỗi cạnh (u,v) E[G]

6 do ifd[v] >d[u] + w(u,v)

7 then return FALSE

8 return TRUE

Hình 2.4 minh hoạ việc thực hiện thuật toán Bellman-Ford trên một đồ thị với

5 đỉnh Sau khi khởi tạo các giá trị của d và  của tất cả các đỉnh ở dòng 1, thuật

toán thực hiện duyệt |V| - 1 lần qua tất cả các cạnh của đồ thị Mỗi lần duyệt là một

lần thực hiện các thao tác của vòng lặp for từ dòng 2 đến 4, bao gồm việc giãn từng cạnh của đồ thị mỗi cạnh một lần Hình 2.4(b)-(e) minh hoạ trạng thái của thuật toán sau mỗi vòng lặp để duyệt tất cả các cạnh của đồ thị Sau khi thực hiện xong

|V|-1 lần duyệt, dòng 5 đến 8 kiểm tra xem trong đồ thị có một chu trình với trọng

số âm đến được từ s không và trả về giá trị bool thích hợp (Chúng ta sẽ tìm hiểu tại

sao các dòng lệnh từ 5 đến 8 kiểm tra được điều đó sau đây một chút)

Thuật toán Bellman-Ford chạy trong thời gian O(VE), vì bước khởi tạo trên dòng 1 có độ phức tạp O(V), trong tất cả |V|-1 lần duyệt các cạnh của đồ thị, từng

lần duyệt có độ phức tạp O(E),và vòng for từ dòng 5 đến 7 có độ phức tạp O(E)

Để chứng minh tính đúng đắn của thuật toán Bellman-Ford, chúng ta bắt đầu

bằng cách chứng minh rằng nếu không có chu trình trọng số âm đến được từ s, thuật

Trang 30

toán tính đúng trọng số đường đi ngắn nhất của tất cả các đỉnh đến được từ đỉnh nguồn

Hình 2.4 Thực hiện thuật toán Bellman-Ford Đỉnh nguồn là đỉnh s Các giá trị

d được ghi bên trong các đỉnh, và các cạnh tô đậm chỉ ra các giá trị đỉnh trước: nếu

Trang 31

cạnh (u,v) được tô đậm thì [v] = u Trong ví dụ riêng biệt này, mỗi lần duyệt giãn các cạnh theo thứ tự (t,x), (t,y), (t,z), (x,t), (y,x), (y,z), (z,x), (z,s), (s,t), (s,y) (a) tình

huống ngay trước khi thứ hiện lần duyệt đầu tiên trên các cạnh (b)-(e) tình huống

sau mỗi lần duyệt liên tiếp trên các cạnh Các giá trị của d và  trong phần (e) là giá trị cuối cùng Thuật toán Bellman-Ford trả về giá trị TRUE trong ví dụ này

Định lý 2.4 (Tính đúng đắn của thuật toán Bellman-Ford)

Giả sử thuật toán Bellman-Ford được thực hiện trên một đồ thị định hướng có trọng số

G = (V,E) với đỉnh nguồn s và hàm trọng số w : E  R Nếu G không chứa các chu

trình trọng số âm có thể đến được từ s, thuật toán sẽ trả về giá trị TRUE, chúng ta

có d[v] = (s,v) với mọi đỉnh v, và đồ thị con đỉnh trước G là cây đường đi ngắn

nhất với gốc là s Nếu G chứa một chu trình trọng số âm đến được từ đỉnh s, thuật

toán trả về giá trị FALSE

Chứng minh

Giả sử đồ thị không chứa chu trình trọng số âm đến được từ đỉnh s Trước tiên chúng ta chứng minh rằng khi kết thúc thuật toán, d[v] = (u,v) với mọi đỉnh v  V Nếu đỉnh v đến được từ s, bổ đề 2.2 đã chứng minh điều này Nếu v không đến được

từ s, điều này được suy ra từ tính chất không tồn tại đường đi Như vậy nó đã được

chứng minh Theo tính chất đồ thị con đỉnh trước, cùng với điều vừa chứng minh

trên, ta suy ra được G là cây đường đi ngắn nhất Bây giờ, chúng ta sử dụng điều vừa chứng minh trên để chứng minh rằng thuật toán sẽ trả về giá trị TRUE

= d(u) + w(u,v)

Trang 32

và do vậy không có cặp đỉnh (u,v) nào thoả mãn dòng 6 và do vậy thuật toán BELLMAN-FORD trả về giá trị TRUE

Ngược lại, giả sử đồ thị G chứa một chu trình trọng số âm có thể đến được từ

s Giả sử chu trình đó là <v0,v1, , vk>, trong đó v0 = vk Khi đó

d[vi-1] + w(vi-1,vi) với i = 1,2, , k Cộng vế với vế của các bất đẳng thức đó theo các đỉnh trên chu trình c, chúng ta có

và trả về FALSE trong trường hợp ngược lại

2.2 Thuật toán Dijkstra

Thuật toán Dijkstra giải bài toán đường đi ngắn nhất từ một đỉnh trên một dồ

thị định hướng G = (V,E) cho trường hợp trong đó mọi cạnh của đồ thị đều có trọng

số không âm Trong phần này, chúng ta sẽ giả sử w(u,v) 0 với mọi cạnh (u,v) E

Thuật toán Dijkstra duy trì một tập S các đỉnh mà trọng số đường đi ngắn nhất của nó từ đỉnh s đã được xác định Thuật toán lặp lại việc chọn một đỉnh u  V - S với đánh giá đường đi ngắn nhất nhỏ nhất, bổ sung u vào S, và giãn tất cả các cạnh

đi ra khỏi u Trong cài đặt sau đây, chúng ta sử dụng một hàng đợi ưu tiên nhỏ nhất

Q, với khoá là giá trị của d

Trang 33

Thuật toán Dijkstra giãn tất cả các cạnh như minh hoạ trong hình 2.6 Dòng 1

thực hiện thủ tục khởi tạo các giá trị của d và  như thường lệ và dòng 2 khởi tạo tập S rỗng Thuật toán duy trì một bất biến là Q = V – S tại điểm bắt đầu của mỗi

vòng lặp while từ dòng 4 đến 8 Dòng 3 khởi tạo hàng đợi ưu tiên nhỏ nhất Q để

chứa tất cả các đỉnh của V; do S =  tại thời điểm đó, bất biến là đúng sau dòng 3

Mỗi lần chạy qua vòng lặp while từ dòng 4 đến 8, một đỉnh u được lấy ra từ Q = V -

S và được bổ sung vào S, và do vậy duy trì được tính bất biến (Lần đầu tiên chạy

qua vòng lặp này, u = s.) Đỉnh u, do vậy là đỉnh có đánh giá đường đi nhỏ nhất trong tập V – S Sau đó, các dòng 7-8 giãn mỗi cạnh (u,v) đi ra khỏi u, cập nhật đánh giá d[v] và đỉnh trước [v] nếu như đường đi ngắn nhất đến v có thể được cải thiện bằng cách đi qua u Quan sát ta sẽ thấy các đỉnh không bao giờ được chèn vào Q sau dòng 3 và một đỉnh được lấy ra từ Q và bổ sung vào S đúng một lần Do vậy

vòng lặp while trên các dòng 4-8 lặp chính xác |V| lần

Trang 34

Hình 2.6 Thực hiện thuật toán Dijkstra.Đỉnh nguồn s là đỉnh bên trái nhất Các

đánh giá đường đi ngắn nhất được ghi bên trong các đỉnh, và các cạnh tô đậm chỉ ra các giá trị đỉnh trước Các đỉnh màu đen là các đỉnh trong tập S, các đỉnh màu trắng

là các đỉnh trong hàng đợi ưu tiên nhỏ nhất Q = V – S (a) Tình huống ngay trước lần lặp đầu tiên của vòng lặp while ở các dòng 4-8 Các đỉnh tô đậm có giá trị d nhỏ nhất và được chọn làm đỉnh u trong dòng 5 (b)-(f) Tình huống sau mỗi lần lặp liên tiếp của vòng lặp while Các đỉnh tô đậm trong mỗi phần được chọn làm đỉnh u trong dòng 5 của lần lặp tiếp theo Các giá trị d và  trong phần (f) là các giá trị cuối

cùng

Vì thuật toán Dijkstra luôn chọn đỉnh gần s nhất trong tập V - S để bổ sung vào tập S, thuật toán Dijkstra thực chất sẽ tạo ra các đường đi ngắn nhất Điểm mấu chốt

là chỉ mỗi khi đỉnh u được bổ sung vào đỉnh S, ta có d[u] = (s,u)

Hình 2.7 Chứng minh định lý 2.6 Tập S là không rỗng ngay trước khi đỉnh u được

bổ sung vào nó Một đường đi ngắn nhất từ đỉnh s đến đỉnh u có thể được phân tích

Trang 35

thành s x y u

p p

không

Định lý 2.6 (Tính đúng đắn của thuật toán Dijkstra)

Thuật toán Dijkstra, chạy trên một đồ thị định hướng, có trọng số G = (V,E) với hàm trọng số không âm w và đỉnh nguồn s, kết thúc với d = (s,v) với mọi đỉnh

uV

Chứng minh

Chúng ta sử dụng bất biến sau đây của vòng lặp

Tại thời điểm bắt đầu vòng lặp while từ dòng 4 đến 8, d[v] =(s,v) với mỗi đỉnh

v  S

- Khởi tạo: đầu tiên, S= , và do đó bất biến là đúng

- Duy trì: chúng ta sẽ chứng minh rằng trong mỗi lần lặp, d[u] =(s,u) đối với

đỉnh u được bổ sung vào S Giả thiết phản chứng, giả sử u là đỉnh đầu tiên mà đối với nó d[u] (s,u) khi nó được bổ sung vào S Chúng ta sẽ tập trung vào tình huống

tại thời điểm khởi đầu của một lần lặp của vòng lặp while trong đó u được bổ sung

vào S và suy ra một điều mâu thuẫn rằng d[u] =(s,u) trong thời điểm bằng cách xét một đường đi ngắn nhất từ s đến u Chúng ta phải có us vì s là đỉnh đầu tiên được

bổ sung vào S và d(s) = (s,s) = 0 tại thời điểm đó Vì u khác s, chúng ta cũng có

S ngay trước khi u được bổ sung vào S Như vậy phải có một đường đi nào đó từ

điều đó mâu thuẫn với giả thiết d[u] (s,u) Vì có ít nhất một đường đi nên sẽ có

một đường đi ngắn nhất p từ s đến u Trước khi bổ sung u vào S, đường đi u nối một đỉnh trong S, (đỉnh s), và một đỉnh trong V - S (đỉnh u) Chúng ta hãy xét đỉnh đầu tiên y trong p sao cho y V – S, và gọi xS là đỉnh trước của nó Như minh hoạ trong

hình vẽ 2.7, đường đi p có thể được tách ra thành sp1 xyp2 u (Các

đường đi p1 và p2 đều có thể không có cạnh nào)

Trang 36

Chúng ta sẽ chứng tỏ rằng d[y] = (s,y) khi u được bổ sung vào S Để chứng minh điều này, chú ý rằng xS và u được chọn là đỉnh đầu tiên sao cho d[u] (s,u) khi nó được bổ sung vào s, chúng ta có d[x] = (s,x) khi x được bổ sung vào S Cạnh (x,y) được giãn vào thời điểm đó, nên ta suy ra d[y] = (s,y) khi u được bổ sung vào S theo tính chất hội tụ

Bây giờ chúng ta có thể suy ra được d[u] = (s,u) Vì y xuất hiện trước u trên đường đi ngắn nhất từ s đến u và mọi cạnh của đồ thị đều có trọng số không âm, nên đường đi p2 cũng có trọng số không âm, và do vậy suy ra (s,y) (s,u), và do vậy ta có

d[y] = (s,y) (s,u) d[u] (theo tính chất chặn trên) (2.2)

Nhưng vì cả hai đỉnh u và y đều nằm trong V - S khi u được chọn trong dòng 5, chúng ta có d[u] d[y] Như vậy từ hai bất đẳng thức trong (2.2) thực ra là các đẳng thức và do vậy ta có d[y] = (s,y) = (s,u) = d[u]

Do vậy, d[u] = (s,u), mâu thuẫn với cách chọn u của chúng ta Chúng ta có thể kết luận rằng d[u] = (s,u) khi u được bổ sung vào S, và đẳng thức này được duy trì tại mọi thời điểm sau đó khi một đỉnh u nào đó được bổ sung vào S

Kết thúc: Tại thời điểm kết thúc, Q= , cùng với bất biến chúng ta đã thấy rằng Q

= V – S, điều đó có nghĩa là S = V Do vậy, d[u] = (s,u) với mọi đỉnh u V

Hệ quả 2.7

Nếu chúng ta chạy thuật toán Dijkstra trên một đồ thị định hướng có trọng số G

= (V,E) với một hàm trọng số không âm w và một đỉnh nguồn s, khi kết thúc thuật toán, đồ thị đỉnh trước G sẽ là một cây đường đi ngắn nhất có gốc là s

Chứng minh

Trực tiếp suy ra từ định lý 2.6 và tính chất đồ thị con đỉnh trước

Phân tích

Thuật toán Dijkstra Nó duy trì hàng đợi ưu tiên nhỏ nhất bằng cách gọi 3 toán

tử hàng đợi ưu tiên: INSERT (ẩn trong dòng 3), EXTRACT-MIN (dòng 5), và DECREASE-KEY (ẩn trong RELAX, được gọi trong dòng 8) INSERT được gọi

một lần cho mỗi đỉnh, cũng giống như với EXTRACT-MIN Vì mỗi đỉnh vV được

Trang 37

bổ sung vào tập S đúng một lần, mỗi cạnh trong danh sách kề của nó Adj[v] được

duyệt (trong vòng lặp for ở các dòng 7-8) đúng một lần trong quá trình thực hiện

thuật toán Vì tổng số cạnh trong tất cả các danh sách kề là |E|, vậy có tổng số |E| lần

lặp trong vòng lặp for, và như vậy có tổng số tối đa |E| thao tác DECREASE-KEY

(Lưu ý ở đây một lần nữa chúng ta lại sử dụng lập luận theo tập hợp)

Thời gian chạy của thuật toán Dijkstra phụ thuộc vào việc hàng đợi ưu tiên nhỏ nhất được cài đặt như thế nào.Đầu tiên xét trường hợp chúng ta duy trì hàng đợi ưu tiên nhỏ nhất bằng cách tận dụng các đỉnh được đánh số từ 1 đến |V| Chúng ta đơn giản lưu trữ d[v] trong ô thứ v của một mảng Mỗi thao tác INSERT và

DECREASE-KEY cần O(1) thời gian, và mỗi thao tác EXTRACT-MIN cần O(V)

thời gian (vì chúng ta phải tìm kiếm trên toàn bộ mảng), như vậy toàn bộ thời gian

cần thiết sẽ là O( + E) = O(V)

Nếu đồ thị khá thưa trong trường hợp riêng E = O( / ) thực tế chúng ta

nên cài đặt hàng đợi ưu tiên nhỏ nhất với một min-heap nhị phân Mỗi thao tác

EXTRACT-MIN cần O(lgV) Như trước, có |V| thao tác như vậy Thời gian để xây dựng một min-heap là O(V) Mỗi thao tác DECREASE-KEY cần O(lgV), và vẫn có tối đa |E| thao tác như vậy Tổng thời gian chạy là O((V+E)lgV), là O(ElgV) nếu

như mọi đỉnh đều đến được từ đỉnh nguồn Thời gian chạy này là một cải tiến

trường hợp chung O( ) khi trường hợp E = O( /lgV)

Trong thực tế, chúng ta có thể đạt đến một thời gian chạy O(VlgV + E) bằng

cách cài đặt hàng đợi ưu tiên nhỏ nhất với một Fibonaci heap Các giá cho mỗi một

trong |V| thao tác EXTRACT-MIN là O(lgV) và mỗi lời gọi DECREASE-KEY (tối

đa |E| lời gọi) chỉ cần O(1) Trong lịch sử, cấu trúc heap Fibonaci được phát triển

dựa trên việc quan sát rằng thuật toán Dijkstra thường có nhiều lời gọi đến DECREASE-KEY hơn lời gọi đến EXTRACT-MIN, nên bất kì việc giảm thời gian

của mỗi thao tác DECREASE-KEY nào về O(lgV) mà không tăng thời gian

ETRACT-MIN đều dẫn đến một thuật toán về mặt tiệm cận nhanh hơn heap nhị phân

Ngày đăng: 25/05/2016, 22:46

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
2. Trần Quốc Chiến, “Thuật toán hoán chuyển nguồn đích có trọng số tìm luồng cực đại”. Tạp chí Khoa học &amp; Công nghệ, Đại học Sư phạm Đà Nẵng, 4(21)/2007,1-6 Sách, tạp chí
Tiêu đề: Thuật toán hoán chuyển nguồn đích có trọng số tìm luồng cực đại”. "Tạp chí Khoa học & Công nghệ, Đại học Sư phạm Đà Nẵng
5. Glenn Seeman, AI for Game Developers – David M.Bourg (bản điện tử) - http://books.google.com.vn/books?id=Sz-Sqvm-hSYC&amp;printsec=frontcover&amp;hl=vi#v=onepage&amp;q&amp;f=false Sách, tạp chí
Tiêu đề: http://books.google.com.vn/books?id=Sz-Sqvm-
3. Brian Schwab, AI Game Engine Programming (bản điện tử) - http://books.google.com.vn/books?id=UbMLAAAAQBAJ&amp;printsec=frontcover&amp;hl=vi#v=onepage&amp;q&amp;f=false Link
1. Trần Quốc Chiến, Giáo trình lý thuyết đồ thị, Đại học Sư phạm Đà Nẵng Khác
4. Dijkstra.E, A note on two problems in connection with graphs, Numerische Mathematik, Vol.1, 1959 Khác
6. H.Rosen Kenneth, Toán rời rạc ứng dụng trong tin học (bản dịch tiếng Việt) Nxb KHKT, Hà Nội, 1997 Khác
7. H.Cormen Thomas, Charles E.Leiserson, Ronald L.Rivest, Introduction To Algorithms, The MIT Press, 1999 Khác
8. H. Cormen Thomas , Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms, Second Edition. MIT Press and McGraw- Hill, 2001. Section 24.1: The Bellman-Ford algorithm, pp. 588–592 Khác
9. H. Cormen Thomas , Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms, Second Edition. MIT Press and McGraw- Hill, 2001 Khác
10. J. Misra K. M. Chandy, Distributed Computation on Graphs, Shortest Path Algorithms, University of Texax at Autin, November 1982 Khác
11. Richard Bellman: On a Routing Problem, Quarterly of Applied Mathematics, 16(1), pp. 87–90, 1958 Khác

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w