Tải bản đầy đủ (.pdf) (75 trang)

Bài toán luồng với chi phí nhỏ nhất và các ứng dụng

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.07 MB, 75 trang )

BỘ 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


BỘ 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



MỤC LỤC
Trang
Lời cam đoan

1

Các chữ viết tắt

2

Danh mục các bảng

3

Danh mục các hình

4

MỞ ĐẦU

5

Chương 1 - LÝ THUYẾT ĐỒ THỊ

8

1.1. Định nghĩa đồ thị

8


1.2. Các khái niệm

9

1.2.1. Cạnh liên thuộc, đỉnh kề, bậc

9

1.2.2. Đường đi, chu trình, sự liên thông

11

1.3. Biểu diễn đồ thị

14

1.3.1. Ma trận liền kề

14

1.3.2. Danh sách cạnh

16

1.3.3. Danh sách kề

18

1.4. Các thuật toán tìm kiếm trên đồ thị


20

1.4.1. Tìm kiếm theo chiều sâu

20

1.4.2. Tìm kiếm theo chiều rộng

21

1.5. Bài toán đường đi ngắn nhất

23

1.5.1. Các khái niệm mở đầu

23

1.5.2. Thuật toán Ford-Bellman

25

1.5.3. Thuật toán Dijkstra

27

Tóm tắt chương 1
Chương 2 - BÀI TOÁN LUỒNG VỚI CHI PHÍ NHỎ NHẤT

30

31


2.1. Giới thiệu

31

2.1.1. Phát biểu bài toán

31

2.1.2. Các giả thiết

32

2.1.3. Đồ thị thặng dư

32

2.2. Điều kiện tối ưu của bài toán

33

2.2.1. Điều kiện tối ưu về chu trình âm

33

2.2.1. Điều kiện tối ưu về chi phí rút gọn

33


2.2.3. Điều kiện tối ưu bổ sung

35

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

Tóm tắt chương 2
Chương 3 – CÁC THUẬT TOÁN

45
46

3.1. Thuật toán khử chu trình âm

46

3.1.1. Tư tưởng thuật toán

46

3.1.2. Mô tả thuật toán

46

3.1.3. Các bước thực hiện thuật toán

46

3.1.4. Độ phức tạp thuật toán

48

3.2. Thuật toán tìm đường đi ngắn nhất liên tiếp


48

3.2.1. Tư tưởng thuật toán

48

3.2.2. Mô tả thuật toán

48


3.2.3. Các bước thực hiện thuật toán

50

3.2.4. Độ phức tạp thuật toán

53

3.3. Thuật toán Primal-dual

53

3.3.1. Tư tưởng thuật toán

53

3.3.2. Mô tả thuật toán


53

3.3.3. Các bước thực hiện thuật toán

54

3.3.4. Độ phức tạp thuật toán

56

3.4. Các thuật toán cải tiến

57

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

Tóm tắt chương 3
Chương 4 – CÀI ĐẶT THUẬT TOÁN VÀ ĐÁNH GIÁ

61
62

4.1. Mục đích thực nghiệm


62

4.2. Các thuật toán lựa chọn

62

4.3. Kết quả thực nghiệm

62

4.3.1. Môi trường thực nghiệm

62

4.3.2. Kết quả Benchark

63

4.4. Đánh giá kết quả thực nghiệm

67

Tóm tắt chương 4

68

KẾT LUẬN

69


TÀI LIỆU THAM KHẢO

70


LỜ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

1


CÁ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

2


DANH 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

3


DANH MỤC CÁC HÌNH
Trang
Hình 1.1: Ví dụ về mô hình đồ thị

8

Hình 1.2: Phân loại đồ thị

9

Hình 1.3: Minh họa đường đi trên đồ thị

11

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.1: Ví dụ về mạng vận chuyển

31

Hình 2.2: Ví dụ về đồ thị thặng dư

33

Hình 2.3: Minh họa bài toán giao việc

40

Hình 2.4: Minh họa bài toán vận chuyển

42

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 3.3: Minh họa thuật toán Primal-dual

56

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

4



MỞ ĐẦ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í

5


nhỏ 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:

6


Cà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á.

7


Chươ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:
G = (V, E)
V gọi là tập các đỉnh (Vertices) và E gọi là tập các cạnh (Edges). Có thể
coi E là tập các cặp (u, v), với u và v là hai đỉnh của V.
Một số hình ảnh của đồ thị:

Sơ đồ mạng giao thông

Mạng mạng máy tính

Hình 1.1: Ví dụ về mô hình đồ thị
Có thể phân loại đồ thị theo đặc tính và số lượng của tập các cạnh E: Cho
đồ thị G = (V, E). Định nghĩa một cách hình thức:
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.


8


3. 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.

9



Vớ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ả

10


Mộ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ị

11


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ư 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ó.
12


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.
Đị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
13


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 đồ 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.
14


Trong đó:
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)
15



- 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
hỏi n2 ô nhớ để lưu các phần tử ma trận, điều đó gây lãng phí bộ nhớ dẫn tới việc
không thể biểu diễn được đồ thị với số đỉnh lớn.
- Với một đỉnh u bất kỳ của đồ thị, nhiều khi ta phải xét tất cả các đỉnh v
khác kề với nó, hoặc xét tất cả các cạnh liên thuộc với nó. Trên ma trận liền kề
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
16



cặ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)

17


Nhượ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

18


liề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ó.
19



Nhượ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 v0 nà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:
Thủ tục DFS(v):
begin
Tham_dinh(v);
Chuaxet[v]:=false;
for u ∈ Ke(v) do
if Chuaxet[u] then DFS(u);
end;
20



×