Đồ 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 mạng giao thông.. Do đó, trong một số trường hợp có thể không qu
Trang 1BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI -
Nguy ễn Đăng Khoa
BÀI TOÁN LU ỒNG VỚI CHI PHÍ NHỎ NHẤT VÀ CÁC ỨNG DỤNG
LUẬN VĂN THẠC SỸ KỸ THUẬT
Công ngh ệ thông tin
Hà N ội - 2016
Trang 2BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI -
Nguy ễn Đăng Khoa
Chuyên nghành: Công nghệ thông tin
BÀI TOÁN LU ỒNG VỚI CHI PHÍ NHỎ NHẤT VÀ CÁC ỨNG DỤNG
LUẬN VĂN THẠC SỸ KỸ THUẬT
Công ngh ệ thông tin
Giáo viên hướng dẫn: PGS.TS Nguyễn Đức Nghĩa
Hà N ội - 2016
Trang 3Chương 2 - BÀI TOÁN LUỒNG VỚI CHI PHÍ NHỎ NHẤT 31
Trang 42.1 Giới thiệu 31
2.2.1 Điều kiện tối ưu về chi phí rút gọn 33
2.3 Mối quan hệ giữa luồng tối ưu và khả năng thông qua tại các đỉnh 36 2.4 Ứng dụng của bài toán luồng với chi phí cực tiểu 38 2.4.1 Ứng dụng trong bài toán giao việc 38 2.4.2 Ứng dụng trong bài toán vị trí rời rạc 41 2.4.3 Ứng dụng trong bài toán vận chuyển 41 2.4.4 Ứng dụng trong bài toán tối ưu mạng các đường bay 43 2.4.5 Ứng dụng trong bài toán tối ưu hóa sản xuất-tồn kho 44
3.2 Thuật toán tìm đường đi ngắn nhất liên tiếp 48
Trang 53.2.3 Các bước thực hiện thuật toán 50
3.4.1 Cải tiến thuật toán tìm đường đi ngắn nhất liên tiếp 57 3.4.2 Cải tiến thuật toán khử chu trình âm 60
Trang 6L ỜI CAM ĐOAN
Tôi xin cam đoan rằng:
Số liệu và kết quả nghiên cứu trong luận văn này là hoàn toàn trung thực
và chưa từng được sử dụng hoặc công bố trong bất kỳ công trình nào khác
Tác gi ả luận văn
Nguy ễn Đăng Khoa
Trang 7CÁC CH Ữ VIẾT TẮT SCC Simple cycle canceling algorithm MMCC Minimum mean cycle canceling algorithm CAT Cancel and tighten algorithm
SSP Successive shortest path algorithm CAS Capacity scaling algorithm
COS Cost scaling algorithm
Trang 8DANH M ỤC CÁC BẢNG
Trang
Bảng 4.1: Thời gian chạy các thuật toán với đồ thị NETGEN 63
Bảng 4.2: Thời gian chạy các thuật toán với đồ thị GOTO 65
Bảng 4.3: Thời gian chạy các thuật toán với đồ thị ROAD 66
Bảng 4.4: Thời gian chạy các thuật toán với đồ thị GRIDGRAPH 67
Trang 9DANH M ỤC CÁC HÌNH
Trang
Hình 1.4: Minh họa đồ thị liên thông mạnh và đồ thị liên thông yếu 13 Hình 1.5: Minh họa biểu diễn đồ thị bằng ma trận kề 15 Hình 1.6: Minh họa biểu diễn đồ thị bằng danh sách cạnh 17 Hình 1.7: Minh họa biểu diễn đồ thị bằng danh sách móc nối 19
Hình 2.5: Minh họa bài toán tối ưu mạng đường bay 43 Hình 2.6: Minh họa bài toán tối ưu sản xuất-tồn kho 44 Hình 3.1: Minh họa thuật toán khử chu trình âm 48 Hình 3.2: Minh họa thuật toán đường đi ngắn nhất liên tiếp 52
Hình 4.1: Đồ thị so sánh thời gian chạy các thuật toán (NETGEN-8) 64 Hình 4.2: Đồ thị so sánh thời gian chạy các thuật toán (NETGEN-SR) 64 Hình 4.3: Đồ thị so sánh thời gian chạy các thuật toán (GOTO-8) 65 Hình 4.4: Đồ thị so sánh thời gian chạy các thuật toán (GOTO-SR) 66
Trang 10M Ở ĐẦU
1 Lý do chọn đề tài
Đồ thị được sử dụng để giải 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 hóa 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 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 mạng giao thông Chúng ta cũng còn sử dụng đồ thị để
giải các bài toán về lập lịch, thời khóa biểu, và phân bố tần số cho các trạm phát thanh và truyền hình…
Bài toán luồng chi phí cực tiểu là một trong những bài toán tối ưu hóa có ứng dụng quan trọng trong lĩnh vực khoa học máy tính, kinh tế,… Bài toán luồng chi phí nhỏ nhất là một biến thể của bài toán luồng cực đại trong mạng
2 M ục tiêu và nhiệm vụ nghiên cứu
- Mục tiêu:
Nghiên cứu các thuật toán giải quyết bài toán luồng với chi phí nhỏ nhất,
cài đặt, kiểm thử
- Nhiệm vụ:
Tìm hiểu lý thuyết đồ thị, nắm chắc các thuật toán tìm kiếm đường, tìm
kiếm điểm trên đồ thị, xây dựng các thuật toán cho bài toán luồng với chi phí
Trang 11nhỏ nhất, lựa chọn dữ liệu cài đặt thuật toán, phân tích so sánh kết quả cài đặt Tìm hiểu các ứng dụng của bài toán
3.Đối tượng và phạm vi nghiên cứu
- Đối tượng nghiên cứu:
Bài toán luồng với chi phí nhỏ nhất
- Phạm vi nghiên cứu:
Lý thuyết đồ thị, các thuật toán cơ bản giải quyết bài toán luồng với chi phí nhỏ nhất, các thuật toán cải tiến, lựa chọn dữ liệu và kiểm thử thuật toán
3 Phương pháp nghiên cứu
Phương pháp nghiên cứu lý thuyết
Phương pháp nghiên cứu thực nghiệm
4 K ết quả dự kiến và phạm vi đề tài
- Xây dựng 3 thuật toán cơ bản cho bài toán luồng với chi phí nhỏ nhất, tìm hiểu một số thuật toán cải tiến cho phép giải quyết bài toán trong trường hợp
dữ liệu là số vô tỉ, hữu tỉ
- Cài đặt, kiểm thử các thuật toán, lựa chọn dữ liệu biểu diễn các dạng đồ
thị theo tiêu chí về quy mô và tính đặc thù đối với các bài toán trong thực tế (đồ
thị biểu diễn hệ thống giao thông, mạng đường dây…), phân tích kết quả kiểm
thử, so sánh, đánh giá các thuật toán
5 Ý nghĩa khoa học và thực tiễn của luận văn
- Ý nghĩa khoa học:
Áp dụng lý thuyết đồ thị vào bài toán luồng với chi phí nhỏ nhất, nghiên
cứu các thuật toán giải quyết các vấn đề đặt ra của bài toán, phân tích so sánh độ
phức tạp tính toán của các thuật toán trên lý thuyết
- Ý nghĩa thực tiễn:
Trang 12Cài đặt, kiểm thử các thuật toán với nhiều bộ dữ liệu khác nhau, qua đó so sánh đánh giá các thuật toán, làm cơ sở lựa chọn thuật toán áp dụng đối với từng dạng bài toán trong thực tế
6 B ố cục luận văn
Luận văn bao gồm: Phần mở đầu, nội dung chính, kết luận, tài liệu tham
khảo Trong đó phần nội dung chính gồm 4 chương:
Chương 1: Lý thuyết đồ thị
Chương 2: Bài toán luồng với chi phí nhỏ nhất
Chương 3: Các thuật toán
Chương 4: Cài đặt thuật toán và đánh giá
Trang 13C hương 1
LÝ THUY ẾT ĐỒ THỊ 1.1 Định nghĩa
Đồ thị là một cấu trúc rời rạc gồm các đỉnh và các cạnh nối các đỉnh đó Được mô tả hình thức như sau:
1 G được gọi là đơn đồ thị nếu giữa hai đỉnh u, v của V có nhiều nhất là 1
cạnh trong E nối từ u tới v
2 G được gọi là đa đồ thị nếu giữa hai đỉnh u, v của V có thể có nhiều hơn 1 cạnh trong E nối từ u tới v
Trang 143 G được gọi là đồ thị vô hướng nếu các cạnh trong E là không định hướng, tức là cạnh nối hai đỉnh u, v bất kỳ cũng là cạnh nối hai đỉnh v, u Hay nói cách khác, tập E gồm các cặp (u, v) không tính thứ tự: (u, v) ≡ (v, u)
4 G được gọi là đồ thị có hướng nếu các cạnh trong E là có định hướng,
có thể có cạnh nối từ đỉnh u tới đỉnh v nhưng chưa chắc đã có cạnh nối từ đỉnh v
tới đỉnh u Hay nói cách khác, tập E gồm các cặp (u, v) có tính thứ tự: (u, v) ≠(v, u) Trong đồ thị có hướng, các cạnh được gọi là các cung Đồ thị vô hướng cũng
có thể coi là đồ thị có hướng nếu như ta coi cạnh nối hai đỉnh u, v bất kỳ tương đương với hai cung (u, v) và (v, u)
Hình 1.2: Phân lo ại đồ thị
1.2 Các khái niệm
Như trên định nghĩa đồ thị G = (V, E) là một cấu trúc rời rạc, tức là các
tập V và E hoặc là tập hữu hạn, hoặc là tập đếm được, có nghĩa là có thể đánh số
thứ tự 1, 2, 3 cho các phần tử của tập V và E Hơn nữa, đứng trên phương diện người lập trình cho máy tính thì chỉ quan tâm đến các đồ thị hữu hạn (V và E là
tập hữu hạn) Sau đây sẽ tìm hiểu một số khái niệm
1.2.1 C ạnh liên thuộc, đỉnh kề, bậc
Đối với đồ thị vô hướng G = (V, E) Xét một cạnh e ∈ E, nếu e = (u, v) thì
ta nói hai đỉnh u và v là kề nhau (adjacent) và cạnh e này liên thuộc (incident)
với đỉnh u và đỉnh v
Trang 15Với một đỉnh v trong đồ thị, ta định nghĩa bậc (degree) của v, ký hiệu deg(v) là số cạnh liên thuộc với v Dễ thấy rằng trên đơn đồ thị thì số cạnh liên thuộc với v cũng là số đỉnh kề với v
Định lý 1.1: Giả sử G = (V, E) là đồ thị vô hướng với m cạnh, khi đó tổng
tất cả các bậc của đỉnh trong V sẽ bằng 2m:
Ch ứng minh: Khi lấy tổng tất cả các bậc đỉnh tức là mỗi cạnh e = (u, v) bất
kỳ sẽ được tính một lần trong deg(u) và một lần trong deg(v) Từ đó suy ra kết
quả
H ệ quả: Trong đồ thị vô hướng, số đỉnh bậc lẻ là số chẵn
Đối với đồ thị có hướng G = (V, E) Xét một cung e ∈ E, nếu e = (u, v) thì
ta nói u nối tới v và v nối từ u, cung e là đi ra khỏi đỉnh u và đi vào đỉnh v Đỉnh
u khi đó được gọi là đỉnh đầu, đỉnh v được gọi là đỉnh cuối của cung e
Với mỗi đỉnh v trong đồ thị có hướng, ta định nghĩa: Bán bậc ra của v ký
hiệu deg+
(v) là số cung đi ra khỏi nó; bán bậc vào ký hiệu deg
-(v) là số cung đi vào đỉnh đó
Định lý 1.2: Giả sử G = (V, E) là đồ thị có hướng với m cung, khi đó tổng
tất cả các bán bậc ra của các đỉnh bằng tổng tất cả các bán bậc vào và bằng m:
Ch ứng minh: Khi lấy tổng tất cả các bán bậc ra hay bán bậc vào, mỗi cung
(u, v) bất kỳ sẽ được tính đúng 1 lần trong deg+(u) và cũng được tính đúng 1 lần trong deg-(v) Từ đó suy ra kết quả
Trang 16Một số tính chất của đồ thị có hướng không phụ thuộc vào hướng của các cung Do đó, trong một số trường hợp có thể không quan tâm đến hướng của các cung và coi các cung đó là các cạnh của đồ thị vô hướng Đồ thị vô hướng đó được gọi là đồ thị vô hướng nền của đồ thị có hướng ban đầu
1.2.2 Đường đi, chu trình, sự liên thông
Định nghĩa 1.3: Đườ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 x0, x1,…, xn-1, xn trong đó
u = x0 , v = xn , (xi , xi+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 dãy các cạnh:
(x0, x1), (x1, x2), …, (xn-1, xn) Đỉ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
Ví d ụ 1.1: Trên đồ thị vô hướng cho trong hình 1: a, d, c, f, e là đường đi
đơn độ dài 4 Còn d, e, c, a không là đường đi, do (c,e) 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ó 2 lần
Hình 1.3: Minh h ọa đường đi trên đồ thị
Trang 17Khá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ư trong trường hợp đồ thị vô hướng, chỉ khác là cần chú ý đến hướng trên các cung
Định nghĩa 1.4:
Đườ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 x0, x1,…, xn-1, xn trong đó u = x0, v = xn, (xi, xi+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 dãy các cung:
(x0, x1), (x1, x2), …, (xn-1, xn) Đỉ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
Ví d ụ 1.2: Trên đồ thị có hướng cho trong hình 1.3: a, d, c, f, e là đường đi
đơn độ dài 4 Còn d, e, c, a không là đường đi, do (c,e) 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ó 2 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 thông tin được với nhau hoặc là 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 không đường đi giữa mọi
cặp đỉnh của đồ thị
Định nghĩa 1.5: Đồ 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ó
Trang 18Như 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
Định nghĩa 1.6: 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ị
Định nghĩa 1.7: Đỉ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ị
Định nghĩa 1.8: Đồ 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ó
Định nghĩa 1.9: Đồ 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à 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 ví dụ dưới đây
Ví d ụ 1.3: Trong hình 1.4 đồ 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.4: Minh h ọa đồ thị liên thông mạnh và đồ thị liên thông yếu
Trang 19Mộ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 đồ 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.10: Đồ 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 một đồ 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 cạnh của đồ thị là đã được định hướng thì kết thúc thủ
tục Ngược lại, chọn e 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 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ó định 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.3 Bi ểu diễn đồ thị
1.3.1 Ma trận liền kề
Giả sử G = (V, E) là một đơn đồ thị có số đỉnh (ký hiệu |V|) là n, không
mất tính tổng quát có thể coi các đỉnh được đánh số 1, 2, , n
Khi đó ta có thể biểu diễn đồ thị bằng một ma trận vuông A = [aij] cấp n
Trang 20Trong đó:
aij = 1 nếu (i, j) ∈ E
aij = 0 nếu (i, j) ∉ E
Quy ước aii= 0 với ∀ i
Đối với đa đồ thị thì việc biểu diễn cũng tương tự trên, chỉ có điều nếu như (i, j) là cạnh thì không phải ta ghi số 1 vào vị trí aij mà là ghi số cạnh nối
giữa đỉnh i và đỉnh j
Hình 1.5: Minh h ọa biểu diễn đồ thị bằng ma trận kề
Các tính chất của ma trận liền kề:
- Đối với đồ thị vô hướng G, thì ma trận liền kề tương ứng là ma trận đối
xứng (aij = aji), điều này không đúng với đồ thị có hướng
- Nếu G là đồ thị vô hướng và A là ma trận liền kề tương ứng thì trên ma trận A:
Tổng các số trên hàng i = Tổng các số trên cột i = Bậc của đỉnh i = deg(i)
Trang 21- Nếu G là đồ thị có hướng và A là ma trận liền kề tương ứng thì trên ma trận A:
Tổng các số trên hàng i = Bán bậc ra của đỉnh i = deg+
(i)
Tổng các số trên cột i = Bán bậc vào của đỉnh i = deg
-(i) Trong trường hợp G là đơn đồ thị, ta có thể biểu diễn ma trận liền kề A tương ứng là các phần tử logic:
aij= TRUE nếu (i, j) ∈ E và aij= FALSE nếu (i, j) ∉ E
Ưu điểm của ma trận liền kề:
- Đơn giản, trực quan, dễ cài đặt trên máy tính
- Để kiểm tra xem hai đỉnh (u, v) của đồ thị có kề nhau hay không, ta chỉ
việc kiểm tra bằng một phép so sánh: auv≠0
Nhược điểm của ma trận liền kề:
- Bất kể số cạnh của đồ thị là nhiều hay ít, ma trận liền kề luôn luôn đòi
việc đó được thực hiện bằng cách xét tất cả các đỉnh v và kiểm tra điều kiện auv
≠0 Như vậy, ngay cả khi đỉnh u là đỉnh cô lập (không kề với đỉnh nào) hoặc đỉnh treo (chỉ kề với 1 đỉnh) ta cũng buộc phải xét tất cả các đỉnh và kiểm tra điều kiện trên dẫn tới lãng phí thời gian
1.3.2 Danh sách c ạnh
Trong trường hợp đồ thị có n đỉnh, m cạnh, ta có thể biểu diễn đồ thị dưới
dạng danh sách cạnh, trong cách biểu diễn này, người ta liệt kê tất cả các cạnh
của đồ thị trong một danh sách, mỗi phần tử của danh sách là một cặp (u, v) tương ứng với một cạnh của đồ thị (Trong trường hợp đồ thị có hướng thì mỗi
Trang 22cặp (u, v) tương ứng với một cung, u là đỉnh đầu và v là đỉnh cuối của cung) Danh sách được lưu trong bộ nhớ dưới dạng mảng hoặc danh sách móc nối
Ví dụ với đồ thị dưới đây:
Hình 1.6: Minh h ọa biểu diễn đồ thị bằng danh sách cạnh
Ưu điểm của danh sách cạnh:
- Trong trường hợp đồ thị thưa (có số cạnh tương đối nhỏ: m < 6n), cách
biểu diễn bằng danh sách cạnh sẽ tiết kiệm được không gian lưu trữ, bởi nó chỉ
cần 2m ô nhớ để lưu danh sách cạnh
- Trong một số trường hợp, ta phải xét tất cả các cạnh của đồ thị thì cài đặt trên danh sách cạnh làm cho việc duyệt các cạnh dễ dàng hơn (thuật toán Kruskal chẳng hạn)
Trang 23Nhược điểm của danh sách cạnh:
Nhược điểm cơ bản của danh sách cạnh là khi ta cần duyệt tất cả các đỉnh
kề với đỉnh v nào đó của đồ thị, thì chẳng có cách nào khác là phải duyệt tất cả các cạnh, lọc ra những cạnh có chứa đỉnh v và xét đỉnh còn lại Điều đó khá tốn
thời gian trong trường hợp đồ thị dày (nhiều cạnh)
1.3.3 Danh sách k ề
Để khắc phục nhược điểm của các phương pháp ma trận kề và danh sách
cạnh, người ta đề xuất phương pháp biểu diễn đồ thị bằng danh sách kề Trong cách biểu diễn này, với mỗi đỉnh v của đồ thị, ta cho tương ứng với nó một danh sách các đỉnh kề với v
Với đồ thị G = (V, E) V gồm n đỉnh và E gồm m cạnh Có hai cách cài đặt danh sách kề phổ biến:
Cách 1: (Forward Star) Dùng một mảng các đỉnh, mảng đó chia làm n đoạn, đoạn thứ i trong mảng lưu danh sách các đỉnh kề với đỉnh i: Ví dụ với đồ
thị trên, danh sách kề sẽ là một mảng A gồm 12 phần tử:
Để biết một đoạn nằm từ chỉ số nào đến chỉ số nào, ta có một mảng lưu vị trí riêng Ta gọi mảng lưu vị trí đó là mảng Head Head[i] sẽ bằng chỉ số đứng
Trang 24liền trước đoạn thứ i Quy ước Head[n + 1] sẽ bằng m Với đồ thị trên thì mảng VT[1 6] sẽ là: (0, 3, 5, 8, 10, 12)
Như vậy đoạn từ vị trí Head[i] + 1 đến Head[i + 1] trong mảng A sẽ chứa các đỉnh kề với đỉnh i
Lưu ý rằng với đồ thị có hướng gồm m cung thì cấu trúc Forward Star cần
phải đủ chứa m phần tử, với đồ thị vô hướng m cạnh thì cấu trúc Forward Star
cần phải đủ chứa 2m phần tử
Cách 2: Dùng các danh sách móc nối, với mỗi đỉnh i của đồ thị, ta cho tương ứng với nó một danh sách móc nối các đỉnh kề với i, có nghĩa là tương ứng với một đỉnh i, ta phải lưu lại List[i] là chốt của một danh sách móc nối Ví
dụ với đồ thị trên, danh sách móc nối sẽ là:
Hình 1.7: Minh h ọa biểu diễn đồ thị bằng danh sách móc nối
Ưu điểm của danh sách kề:
Đối với danh sách kề, việc duyệt tất cả các đỉnh kề với một đỉnh v cho trước là hết sức dễ dàng, cái tên "danh sách kề" đã cho thấy rõ điều này Việc duyệt tất cả các cạnh cũng đơn giản vì một cạnh thực ra là nối một đỉnh với một đỉnh khác kề nó
Trang 25Nhược điểm của danh sách kề:
Về lý thuyết, so với hai phương pháp biểu diễn trên, danh sách kề tốt hơn
hẳn Chỉ có điều, trong trường hợp cụ thể mà ma trận kề hay danh sách cạnh không thể hiện nhược điểm thì ta nên dùng ma trận kề (hay danh sách cạnh) bởi cài đặt danh sách kề phức tạp hơn
1.4 Các thu ật toán tìm kiếm trên đồ thị
1.4.1 Tìm ki ếm theo chiều sâu
Ý tưởng chính của thuật toán có thể trình bày như sau: Ta sẽ bắt đầu tìm
kiếm từ một đỉnh v0nào đó của đồ thị Sau đó chọn u là một đỉnh tuỳ ý kề với v0
và lặp lại quá trình đối với u Ở bước tổng quát, giả sử ta đang xét đỉnh v, nếu
như trong số các đỉnh kề với v tìm được đỉnh w là chưa được xét thì ta sẽ xét đỉnh này (nó sẽ trở thành đã xét) và bắt đầu từ nó ta sẽ bắt đầu quá trình tìm kiếm còn nếu không còn đỉnh nào kề với v là chưa xét thì ta nói rằng đỉnh này đã duyệt xong và quay trở lại tiếp tục tìm kiếm từ đỉnh mà trước đó ta đến được đỉnh v (nếu v=v0, thì kết thúc tìm kiếm)
Có thể nói là tìm kiếm theo chiều sâu bắt đầu từ đỉnh v được thực hiện trên cơ sở tìm kiếm theo chiều sâu từ tất cả các đỉnh chưa xét kề với v Quá trình này có thể mô tả bởi thủ tục đệ qui sau đây:
Trang 26Khi đó, tìm kiếm theo chiều sâu được thực hiện nhờ thuật toán sau:
biến Chuaxet[v] được đặt lại giá trị false nên mỗi đỉnh sẽ được thăm đúng một
lần Thuật toán lần lượt sẽ tiến hành tìm kiếm từ các đỉnh chưa được thăm, vì
vậy, nó sẽ xét qua tất cả các đỉnh của đồ thị (không nhất thiết phải là liên thông)
Để đánh giá độ phức tạp tính toán của thủ tục, trước hết nhận thấy rằng số phép toán cần thực hiện trong hai chu trình của thuật toán (hai vòng for ở
chương trình chính) là cỡ n Thủ tục DFS phải thực hiện không quá n lần Tổng
số phép toán cần phải thực hiện trong các thủ tục này là O(n+m), do trong các
thủ tục này ta phải xét qua tất cả các cạnh và các đỉnh của đồ thị Vậy độ phức
tạp tính toán của thuật toán là O(n+m)
1.4.2 Tìm ki ếm theo chiều rộng
Để ý rằng trong thuật toán tìm kiếm theo chiều sâu đỉnh được thăm càng
muộn sẽ càng sớm trở thành đã duyệt xong Điều đó là hệ quả tất yếu của việc các đỉnh được thăm sẽ được kết nạp vào trong ngăn xếp (STACK) Tìm kiếm theo chiều rộng trên đồ thị, nếu nói một cách ngắn gọn, được xây dựng trên cơ
Trang 27sở thay thế ngăn xếp (STACK) bởi hàng đợi (QUEUE) Với sự cải biên như vậy, đỉnh được thăm càng sớm sẽ càng sớm trở thành đã duyệt xong (tức là càng sớm
dời khỏi hàng đợi) Một đỉnh sẽ trở thành đã duyệt xong ngay sau khi ta xét xong
tất cả các đỉnh kề (chưa được thăm) với nó Thủ tục có thể mô tả như sau:
Trang 28lần Độ phức tạp tính toán của thuật toán là O(m+n)
1.5 Bài toán đường đi ngắn nhất
1.5.1 Các khái ni ệm mở đầu
Trong phần này chúng ta chỉ xét đồ thị có hướng G =(V,E), |V|=n, |E|=m
với các cung được gán trọng số, nghĩa là, mỗi cung (u,v) ∈ E của nó được đặt tương ứng với một số thực a(u,v) gọi là trọng số của nó Chúng ta sẽ đặt a(u,v) =
∞ , nếu (u,v) ∉ E Nếu dãy v0, v1, , vp là một đường đi trên G, thì độ dài của
nó được định nghĩa là tổng sau:
� 𝑎(𝑣𝑖−1
𝑝 𝑖=1
, 𝑣𝑖)
Tức là, độ dài của đường đi chính là tổng của các trọng số trên các cung
của nó (Chú ý rằng nếu chúng ta gán trọng số cho tất cả cung đều bằng 1, thì ta thu được định nghĩa độ dài của đường đi như là số cung của đường đi giống như trong các chương trước đã xét)
Bài toán tìm đường đi ngắn nhất trên đồ thị dưới dạng tổng quát có thể phát
biểu như sau: Tìm đường đi có độ dài nhỏ nhất từ một đỉnh xuất phát s ∈V đến đỉnh
cuối (đích) t ∈ V Đường đi như vậy ta sẽ gọi là đường đi ngắn nhất từ s đến t còn độ
Trang 29dài của nó ta sẽ ký hiệu là d(s,t) và còn gọi là khoảng cách từ s đến t (khoảng cách định nghĩa như vậy có thể là số âm) Nếu như không tồn tại đường đi từ s đến t thì ta
sẽ đặt d(s,t) =∞ Rõ ràng, nếu như mỗi chu trình trong đồ thị đều có độ dài dương, trong đường đi ngắn nhất không có đỉnh nào bị lặp lại (đường đi không có đỉnh lặp
lại sẽ gọi là đường đi cơ bản)
Mặt khác nếu trong đồ thị có chu trình với độ dài âm (chu trình như vậy để gọi
ngắn gọn ta gọi là chu trình âm) thì khoảng cách giữa một số cặp đỉnh nào đó của đồ
thị có thể là không xác định, bởi vì, bằng cách đi vòng theo chu trình này một số đủ
lớn lần, ta có thể chỉ ra đường đi giữa các đỉnh này có độ dài nhỏ hơn bất cứ số thực cho trước nào Trong những trường hợp như vậy, có thể đặt vấn đề tìm đường đi cơ
bản ngắn nhất, tuy nhiên bài toán đặt ra sẽ trở nên phức tạp hơn rất nhiều, bởi vì nó
chứa bài toán xét sự tồn tại đường đi Hamilton trong đồ thị như là một trường hợp riêng
Trước hết cần chú ý rằng nếu biết khoảng cách từ s đến t, thì đường đi ngắn
nhất từ s đến t, trong trường hợp trọng số không âm, có thể tìm được một cách dễ dàng Để tìm đường đi, chỉ cần để ý là đối với cặp đỉnh s, t ∈ V tuỳ ý (s ≠ t) luôn tìm được đỉnh v sao cho:
Thực vậy, đỉnh v như vậy chính là đỉnh đi trước đỉnh t trong đường đi ngắn
nhất từ s đến t Tiếp theo ta lại có thể tìm được đỉnh u sao cho d(s,v) = d(s,u) + a(u,v)
Từ giả thiết về tính không âm của các trọng số dễ dàng suy ra rằng dãy t, v, u, không chứa đỉnh lặp lại và kết thúc ở đỉnh s
Rõ ràng dãy thu được xác định (nếu lật ngược thứ tự các đỉnh trong nó) đường
đi ngắn nhất từ s đến t Từ đó ta có các thuật toán sau đây để tìm đường đi ngắn nhất
từ s đến t khi biết độ dài của nó
Trang 301.5.2 Thu ật toán ford-bellman
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ả đại thể 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] cận trên d[v] sẽ được làm tốt lên: d[v] + 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 kỳ cận trên nào Khi đó, rõ ràng giá trị của mỗi d[v] sẽ cho khoảng cách từ đỉnh s đến đỉnh 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 này sẽ được gọi là thủ
tục gán Nhận thấy rằng để tính khoảng cách từ s đến t, ở đây, ta phải tính khoảng cách từ s đến tất cả các đỉnh còn lại của đồ thị Hiện nay vẫn chưa biết thuật toán nào cho phép tìm đường đi ngắn nhất giữa hai đỉnh làm việc thực sự
hiệu quả hơn những thuật toán tìm đường đi ngắn nhất từ một đỉnh đến tất cả các đỉnh còn lại
Sơ đồ tính toán mà ta vừa mô tả còn chưa xác định, bởi vì còn phải chỉ ra
thứ tự các đỉnh u và v để kiểm tra điều kiện trên Thứ tự chọn này có ảnh hưởng
rất lớn đến hiệu quả của thuật toán
Bây giờ ta sẽ mô tả thuât toán Ford-Bellman tìm đường đi ngắn nhất từ đỉnh s đến tất cả các đỉnh còn lại của đồ thị Thuật toán làm việc trong trường
hợp trọng số của các cung là tuỳ ý, nhưng giả thiết rằng trong đồ thị không có chu trình âm
Th ủ tục của thuật toán Ford_Bellman
Đầu vào:
Đồ thị có hướng G=(V,E) với n đỉnh,
s ∈ V là đỉnh xuất phát, A[u,v], u, v ∈ V, ma trận trọng số;
Trang 31Giả thiết: Đồ thị không có chu trình âm
if d[v] > d[u] +a[u,v] then
Tính đúng đắn của thuật toán có thể chứng minh trên cơ sở trên nguyên lý
tối ưu của quy hoạch động Rõ ràng là độ phức tạp tính toán của thuật toán là
Trang 32O(n3) Lưu ý rằng chúng ta có thể chấm dứt vòng lặp theo k khi phát hiện trong quá trình thực hiện hai vòng lặp trong không có biến d[v] nào bị đổi giá trị Việc này có thể xảy ra đối với k < n-2, và điều đó làm tăng hiệu quả của thuật toán trong việc giải các bài toán thực tế Tuy nhiên, cải tiến đó không thực sự cải thiện được đánh giá độ phức tạp của bản thân thuật toán Đối với đồ thị thưa tốt hơn là sử dụng danh sách kề Ke(v), v∈ V, để biểu diễn đồ thị, khi đó vòng lặp theo u cần viết lại dưới dạng:
Trong trường hợp này ta thu được thuật toán với độ phức tạp O(n,m)
1.5.3 Thu ật toán Dijkstra
Trong trường hợp trọng số trên các cung là không âm thuật toán do Dijkstra đề nghị làm việc hữu hiệu hơn rất nhiều so với thuật toán trình bày trong
mục trước Thuật toán đượ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 Nhãn của mỗi đỉnh cho biết cận của độ dài đường đi ngắn nhất từ s đến
nó Các nhãn này sẽ được biến đổi theo một thủ tục lặp, mà ở 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 một nhãn cố định thì nó sẽ cho ta không phải là cận trên mà là độ dài của đường đi ngắn nhất từ đỉnh s đến nó Thuật toán được mô tả cụ thể như sau
Th ủ tục thuật toán Dijstra
Đầu vào:
Trang 33Đồ thị có hướng G = (V,E) với n đỉnh; s ∈ V là đỉnh xuất phát; ma trận a[u,v], với u,v ∈ V là ma trận trọng số;
Giả thiết: a[u,v] ≥ 0, u,v ∈ V
Trang 34sẽ chứng minh rằng ở lần gặp tiếp theo nếu đỉnh u* thu được nhãn cố định d(u*) chính là độ dài đường đi ngẵn nhất từ s đến u*
Ký hiệu S1 là tập hợp các đỉnh có nhãn cố định còn S2 là tập các đỉnh có nhãn tạm thời ở bước lặp đang xét Kết thúc mỗi bước lặp nhãn tạm thời d(u*
) cho ta độ dài của đường đi ngắn nhất từ s đến u* không nằm trọng trong tập S1,
tức là nó đi qua ít nhất một đỉnh của tập S2 Gọi z ∈ S2là đỉnh đầu tiên như vậy trên đường đi này Do trọng số trên các cung là không âm, nên đoạn đường từ z đến u* có độ dài L > 0 và d(z) < d(u*) – L < d(u*)
Bất đẳng thức này là mâu thuẫn với cách xác định đỉnh u* là đỉnh có nhãn
tạm thời nhỏ nhất Vậy đường đi ngắn nhất từ s đến u* phải nằm trọn trong S1,
và vì thế, d[u*] là độ dài của nó Do ở lần lặp đầu tiên S1 = {s} và sau mỗi lần
lặp ta chỉ thêm vào một đỉnh u* nên giả thiết là d(v) cho độ dài đường đi ngắn
nhất từ s đến v với mọi v ∈ S1 là đúng với bước lặp đầu tiên Theo qui nạp suy
ra thuật toán cho ta đường đi ngắn nhất từ s đến mọi đỉnh của đồ thị
Trang 35Bây giờ ta sẽ đánh giá số phép toán cần thực hiện theo thuật toán Ở mỗi bước lặp để tìm ra đỉnh u cần phải thực hiện O(n) phép toán, và để gán nhãn lại cũng cần thực hiện một số lượng phép toán cũng là O(n) thuật toán phải thực
hiện n-1 bước lặp, vì vậy thời gian tính toán của thuận toán cỡ O(n2
tảng giúp cho chúng ta tiếp cận các nội dung của bài toán luồng với chi phí nhỏ
nhất sẽ được trình bày ở các chương sau một cách dễ dàng hơn
Trên cơ sở nội dung nghiên cứu trong chương 1, chương 2 sẽ nghiên cứu
những vấn đề chung nhất về bài toán luồng với chi phí nhỏ nhất
Trang 36C hương 2 BÀI TOÁN LU ỒNG VỚI CHI PHÍ NHỎ NHẤT 2.1 Gi ới thiệu
2.1.1 Phát biểu bài toán
Gọi G = (N, A) là một đồ thị có hướng với chi phí cij và khả năng thông qua uij gắn với mỗi cạnh (i, j) ∈ A Chúng ta gắn một đỉnh i ∈ N một số bi chỉ
khả năng cung (bi > 0) hoặc cầu (bi < 0) Ví dụ:
7,5
1,8 3,4
Trang 37và bài toán luồng với chi phí cực tiểu có một giải pháp khả thi
Giả thiết 4: Chúng ta giả sử rằng đồ thị G chứa một đường đi có hướng không có giới hạn (nghĩa là tất cả các cung trên đường đi có độ thông qua vô
độ thông qua thặng dư rij = xij Đồ thị thặng dư chỉ chứa các cung có độ thông qua thặng dư dương
4/7,5
1/1,8 3/3,4