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

Về thuật toán tìm đường đi ngắn nhất giữa hai điểm trong một đa giác đơn của LEE và PREPARATA

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 (437.16 KB, 55 trang )

Mục lục
Mở đầu

4

1 Kiến thức cơ sở

6

1.1

1.2

1.3

1.4

Lý thuyết đồ thị . . . . . . . . . . . . . . . . . . . . . .
1.1.1 Định nghĩa đồ thị . . . . . . . . . . . . . . . .

6
6

1.1.2

Đường đi trong đồ thị . . . . . . . . . . . . . .

8

1.1.3 Một số tính chất về đường đi trong đồ thị . . .
Tam giác phân đa giác . . . . . . . . . . . . . . . . . .



9
10

1.2.1

Đường gấp khúc đơn điệu và đa giác đơn điệu .

10

1.2.2 Các tính chất . . . . . . . . . . . . . . . . . . .
Độ phức tạp thuật toán . . . . . . . . . . . . . . . . .

12
15

1.3.1

Khái niệm độ phức tạp của thuật toán . . . . .

15

1.3.2
1.3.3
1.3.4

Các định nghĩa . . . . . . . . . . . . . . . . . .
Các tính chất . . . . . . . . . . . . . . . . . . .
Cách tính độ phức tạp của thuật toán . . . . .


16
17
19

1.3.5 Phép tính cơ sở . . . . . . . . . . . . . . . . . .
1.3.6 Dãy các phép tính . . . . . . . . . . . . . . . .
Thuật toán tìm tiếp tuyến của O’Rourke . . . . . . . .

19
19
22

2 Thuật toán Dijkstra và thuật toán tam giác phân
24
2.1 Thuật toán Dijstra . . . . . . . . . . . . . . . . . . . . 24
2.1.1 Thuật toán Dijkstra . . . . . . . . . . . . . . . 24
2.1.2
2.1.3

Chứng minh tính đúng đắn của thuật toán . . .
Độ phức tạp thuật toán Dijkstra . . . . . . . .
1

27
27


2

2.2


Thuật toán tam giác phân đa giác đơn . . . . . . . . . 30
2.2.1 Phân chia đa giác đơn thành các đa giác đơn điệu 31
2.2.2 Thuật toán tam giác phân đa giác đơn điệu . . 31
2.2.3

Thuật toán tam giác phân đa giác đơn . . . . .

36

3 Thuật toán tìm đường đi ngắn nhất giữa hai điểm
37
3.1 Thuật toán của Lee và Preparata . . . . . . . . . . . . 37

3.2

3.1.1

Các định nghĩa . . . . . . . . . . . . . . . . . .

37

3.1.2
3.1.3

Các tính chất . . . . . . . . . . . . . . . . . . .
Thuật toán tạo ra hình ống tay (sleeve) . . . . .

40
40


3.1.4
3.1.5

Độ phức tạp của thuật toán SLEEVE(P) . . . 41
Thuật toán Phễu (Funnel) của Lee và Preparata 42

3.1.6

Chứng minh tính đúng đắn của thuật toán . . .

43

3.1.7 Độ phức tạp thuật toán Phễu . . . . . . . . . .
Thuật toán tìm đường đi ngắn nhất . . . . . . . . . . .
3.2.1 Thuật toán thuật toán chính . . . . . . . . . . .

44
47
48

3.2.2
3.2.3

48
48

Độ phức tạp thuật toán . . . . . . . . . . . . .
Chứng minh tính đúng đắn của thuật toán . . .


Kết luận

52

Tài liệu tham khảo

53


Danh sách hình vẽ
1.1
1.2

Đồ thị hữu hạn . . . . . . . . . . . . . . . . . . . . . .
Minh hoạ điểm nằm bên trái, bên phải đường thẳng . .

7
11

1.3
1.4

Minh hoạ đa giác . . . . . . . . . . . . . . . . . . . . .
Minh hoạ sự tồn tại đỉnh lồi . . . . . . . . . . . . . . .

12
13

1.5


Minh hoạ tính chất đường chéo

13

1.6
1.7

Minh hoạ đường gấp khúc đơn điệu và đa giác đơn điệu. 15
Mô tả quan hệ giữa hai hàm cg(n) và f (n). . . . . . . 16

1.8

Minh hoạ thuật toán tìm tiếp tuyến . . . . . . . . . . .

23

2.1
2.2
2.3

Mô tả đồ thị có trọng số . . . . . . . . . . . . . . . . .
Quá trình tìm đường đi ngắn nhất theo thuật toán . .
Minh hoạ đa giác Y - đơn điệu . . . . . . . . . . . . .

28
29
33

2.4


Minh hoạ quá trình tam giác hoá đa giác Y- đơn điệu

35

3.1
3.2

Minh hoạ cây đối ngẫu . . . . . . . . . . . . . . . . . .
Minh hoạ hình ống tay (Sleeve) . . . . . . . . . . . . .

38
38

3.3
3.4
3.5

Minh hoạ Phễu (Funnel) . . . . . . . . . . . . . . . . .
Minh hoạ hai trường hợp xác định Phễu mới . . . . . .
Minh hoạ tính chất đường ống tay . . . . . . . . . . .

39
39
40

3.6
3.7
3.8

Minh hoạ tính chất của Phễu . . . . . . . . . . . . . .

Minh hoạ hình ống tay(Sleeve) . . . . . . . . . . . . . .
Quá trình tìm đường đi ngắn nhất theo thuật toán Phễu

41
44
47

3.9

Minh họa quá trình tìm đường đi ngắn nhất từ a đến b.

51

3

. . . . . . . . . . . . .


Mở đầu
Hình học tính toán là lĩnh vực nghiên cứu để tìm ra các thuật toán
hiệu quả và thực thi trên máy tính cho những bài toán hình học. Trong
hình học tính toán thường giải quyết các bài toán kinh tế, như: Tìm
địa điểm để đặt các nhà máy, đặt trạm điện, đặt bến xe, tìm đường
đi ngắn nhất cho những chiếc tàu biển,. . .
Tìm đường đi ngắn nhất giữa hai điểm trong một miền hình học là
một trong những vấn đề cơ bản trong hình học tính toán. Điều này có
nhiều ứng dụng trong kỹ thuật rôbốt, kỹ thuật tự động, công nghiệp,
thông tin địa lý . . . Thực tế đó đã thu hút rất nhiều nhà toán học
quan tâm nghiên cứu như: O’Rourke, Dijkstra, Preparata, Lee, Berg,
Kreveld, Guibas, Hershberger, Leven. . .

Bài toán "Tìm đường đi ngắn nhất giữa hai điểm trong một đa
giác đơn"(với khoảng cách theo chuẩn Euclidean) trong mặt phẳng
đã được nhiều nhà toán học đưa ra các thuật toán khác nhau để giải
quyết. Năm 1984, Lee và Preparata đã đưa ra thuật toán cơ bản để
giải quyết bài toán này thông qua việc tam giác phân đa giác (xem
[13]) và năm 1987, Guibas, Hershberger, Leven, Sharir và Tarjan đã
có sự cải tiến thuật toán này (xem [12]).
Trong luận văn này chúng tôi nghiên cứu về thuật toán của Lee và
Preparata (đã có sự cải tiến) để giải bài toán trên. Với lý do đó chúng
tôi chọn đề tài của luận văn là:"Về thuật toán tìm đường đi ngắn nhất
giữa hai điểm trong một đa giác đơn của Lee và Preparata".
Luận văn được trình bày trong ba chương:


5

Chương 1 Kiến thức cơ sở
Với quan điểm là chương cơ sở, trong chương này chúng tôi trình bày
hệ thống kiến thức về lý thuyết đồ thị, tam giác phân đa giác, độ phức
tạp của thuật toán, thuật toán tìm tiếp tuyến của O’Rourke nhằm giúp
làm cơ sở cho việc nghiên cứu thuật toán của Lee và Preparata.
Chương 2 Thuật toán Dijkstra và thuật toán tam giác phân
đa giác
Trong chương này chúng tôi trình bày thuật toán của Dijkstra, thuật
toán phân chia đa giác đơn thành các đa giác y - đơn điệu, thuật toán
tam giác phân đa giác y - đơn điệu, thuật toán tam giác phân đa giác
đơn.
Chương 3 Thuật toán tìm đường đi ngắn nhất giữa hai điểm
trong một đa giác đơn của Lee và Preparata
Trong chương này chúng tôi trình bày thuật toán tạo ra hình ống

tay, thuật toán Phễu của Lee và Preparata có sự cải tiến của Guibas,
Hershberger, Sharir và Tarjan (xem [12]). Trình bày chi tiết thuật toán
chính để giải bài toán "tìm đuờng đi ngắn nhất giữa hai điểm trong
một đa giác đơn".

Luận văn được hoàn thành dưới sự hướng dẫn tận tình của thầy
giáo TS. Phan Thành An. Tác giả xin được bày tỏ lòng biết ơn sâu
sắc tới thầy và xin chân thành cảm ơn các thầy giáo trực tiếp giảng
dạy chuyên ngành với những ý kiến đóng góp trong học tập và làm
luận văn.
Cũng nhân dịp này tác giả xin gửi lời cảm ơn các thầy cô giáo trong
khoa Toán và khoa Đào tạo sau đại học, anh Lê Đình Hậu cao học
13 Hình học - Tôpô, bạn Dương Quốc Nam, các bạn học viên lớp cao
học 14 Hình học - Tôpô, cán bộ giáo viên trường THPT Anh Sơn 3,
gia đình và bạn bè đã động viên, giúp đỡ tôi trong quá trình học tập
nghiên cứu trong suốt khóa học.


Chương 1

Kiến thức cơ sở
Trong chương này chúng tôi trình bày một số kiến thức về lý thuyết
đồ thị, đa giác đơn điệu, phép tam giác phân đa giác, độ phức tạp
thuật toán và thuật toán tìm tiếp tuyến của O’Rourke. Đây là những
kiến thức cơ sở cho chương 2 và chương 3.
1.1

Lý thuyết đồ thị

1.1.1


Định nghĩa đồ thị

Chúng ta nhìn thấy hoặc sử dụng bản đồ các tuyến đường giao
thông của một thành phố, sơ đồ tổ chức một cơ quan, sơ đồ khối tính
toán của một thuật toán, sơ đồ một mạng máy tính . . . Đó là những
ví dụ cụ thể về đồ thị. Đồ thị (graph) là một mô hình toán học được
ứng dụng trong nhiều lĩnh vực khoa học, kỹ thuật và được định nghĩa
như sau.
Định nghĩa 1.1.1 (xem [5]) Đồ thị là một cặp G = (V, E) trong đó:
• V là tập đỉnh (vertex) .
• E ⊆ V × V là tập các cạnh (edge).
Ví dụ 1.1.1 Đồ thị G cho ở hình 1.1 với tập các đỉnh
V = {a, b, c, d, e} và tập các cạnh
E = {(a, b), (a, c), (b, c), (d, b), (d, c), (e, a), (e, b), (e, d)}.
6


7
b
c
a

e

d

Hình 1.1: Đồ thị hữu hạn

Nếu (a, b) là một cạnh của đồ thị thì ta nói rằng đỉnh b kề với đỉnh a

và cả hai đỉnh a và b kề với cạnh (a, b).
Trong đồ thị ở ví dụ 1.1.1 hai đỉnh b và c kề với đỉnh a, ba đỉnh a, b
và d kề với đỉnh e. Do vậy, ta có thể định nghĩa đồ thị bằng ánh xạ
kề như sau:
Định nghĩa 1.1.2 (xem [5]) Đồ thị G là một cặp G = (V, F ), trong
đó:
• V là tập đỉnh.
• F : V −→ Z, F là ánh xạ cho ta mỗi liên hệ giữa một đỉnh với tập
các đỉnh kề với nó (ánh xạ kề).
Sự tương đương của hai định nghĩa được thể hiện bằng mệnh đề sau
đây.
∀x, y ∈ V : (x, y) ∈ E ⇐⇒ y ∈ F (x).
Về bản chất, đồ thị là một tập hợp các đối tượng được biểu diễn
bằng các đỉnh và giữa các đối tượng này có một quan hệ nhị nguyên
biểu diễn bằng các cạnh.
Cặp đỉnh (x, y) ∈ E không sắp thứ tự được gọi là cạnh vô hướng,
còn nó có sắp thứ tự thì được gọi là cạnh có hướng. Vì thế, chúng ta
thường phân các đồ thị thành hai lớp.
Định nghĩa 1.1.3 (xem [5]) Đồ thị chỉ chứa các cạnh vô hướng được
gọi là đồ thị vô hướng, còn đồ thị chỉ chứa các cạnh có hướng gọi là


8

đồ thị có hướng.
Hiển nhiên, mỗi đồ thị vô hướng có thể biểu thị bằng một đồ thị có
hướng bằng cách thay mỗi cạnh vô hướng bằng hai cạnh có hướng
tương ứng.
Định nghĩa 1.1.4 (xem [5]) Đồ thị G = (V, E) được gọi là đối xứng
nếu:

∀x, y ∈ V : (x, y) ∈ E ⇔ (y, x) ∈ E.
Các đồ thị vô hướng là đối xứng.
Định nghĩa 1.1.5 (xem [5]) Đồ thị G = (V, E) mà mỗi cặp đỉnh được
nối nhau bởi không quá một cạnh được gọi là đơn đồ thị (thường gọi
tắt là đồ thị) còn nếu đồ thị có những cặp đỉnh được nối với nhau
nhiều hơn một cạnh thì được gọi là đa đồ thị.
Ta biễu diễn hình học cho đồ thị như sau: Trên mặt phẳng biễu diễn
đỉnh bằng các vòng tròn nhỏ, biểu diễn cạnh vô hướng bằng đoạn
thẳng, biểu diễn cạnh có hướng bằng mũi tên nối hai đỉnh của đồ thị.
Định nghĩa 1.1.6 (xem [5])
1. Hai đỉnh của đồ thị G được gọi là liên thông, nếu trên đồ thị có
đường đi vô hướng nối chúng với nhau.
2. Đồ thị được gọi là liên thông nếu mọi cặp đỉnh của đồ thị đều
liên thông với nhau.
Định nghĩa 1.1.7 (xem [5]) Bậc của một đỉnh đồ thị là số cạnh kề
với đỉnh đó.
1.1.2

Đường đi trong đồ thị

Giả sử G = (V, E) là đồ thị.
Định nghĩa 1.1.8 (xem [5]) Đường đi trong đồ thị là một dãy các
đỉnh:


9

x1 , x2 , . . . , xi , xi+1 , . . . , xk−1 , xk .
sao cho mỗi đỉnh trong dãy (không kể đỉnh đầu tiên) kề với đỉnh trước
nó bằng một cạnh nào đó, nghĩa là:

∀i = 2, 3, ..., k − 1, k : (xi−1 , xi ) ∈ E
Ta nói rằng đường đi này đi từ đỉnh đầu xi đến đỉnh cuối xk . Số cạnh
của đường đi được gọi là độ dài của đường đi đó .
Đường đi đơn là đường đi mà các đỉnh trên nó khác nhau từng đôi
một.
Trong một đồ thị, đỉnh nút là đỉnh kề với chính nó. Hai cạnh có ít
nhất một đỉnh chung được gọi là hai cạnh kề nhau.
Định nghĩa 1.1.9 (xem [5]) Đồ thị G được gọi là đồ thị có trọng
số nếu mỗi cạnh (i, j) của đồ thị được gán một số nguyên không âm
C(i, j).
• Nhãn C(i, j) trên cạnh (i, j) của đồ thị thường biễu diễn "chi phí"
thực tế đi qua cạnh này.
• Đường đi có trọng số bé nhất:
– Độ dài của đường đi trong đồ thị có trọng số bằng tổng các
trọng số của các cạnh trên đường đi đó.
– Độ dài đường đi có trọng số bé nhất đi từ đỉnh a đến đỉnh b
gọi là khoảng cách từ đỉnh a đến đỉnh b.
– Nếu không có đường đi từ a đến b thì ta đặt khoảng cách bằng
∞.
1.1.3

Một số tính chất về đường đi trong đồ thị

Định lý 1.1.1 (xem [5]) Giả sử đồ thị G có n đỉnh. Tồn tại đường đi
từ đỉnh a đến đỉnh b trên đồ thị G khi và chỉ khi tồn tại một đường đi
từ a đến b trên đồ thị này với độ dài không vượt quá n − 1.
Chứng minh. Giả sử có đường đi từ đỉnh a tới đỉnh b. Ta có thể chọn:


10


< a = x1 , x2 , . . . , xk = b, trong đó x1 = xk >
là đường đi có độ dài ngắn nhất.
Độ dài của đướng đi là k − 1. Nếu k − 1 ≤ n − 1 thì định lý được
chứng minh.
Nếu ngượcc lại k > n − 1, nghĩa là k > n, thì trong dãy đỉnh của
đường đi sẽ có ít nhất hai đỉnh trùng nhau, chẳng hạn xi = xj . Khi
đó thì:
< a = x1 , x2 , . . . , xi , xi+1 , . . . , xk−1 , xk = b >
cũng là đường đi từ a đến b nhưng với độ dài ngắn hơn. Suy ra mâu
thuẫn với giả thiết của đường đi ngắn nhất.

Định lý 1.1.2 (xem [5]) Tổng tất cả các bậc của các đỉnh trong một
đồ thị bằng hai lần số cạnh của đồ thị đó.
Chứng minh. Ta tính bậc của các đỉnh. Mỗi đỉnh thuộc một cạnh
nào đó thì bậc của nó tăng thêm 1, mà mỗi cạnh thì có hai đỉnh.

1.2
1.2.1

Tam giác phân đa giác
Đường gấp khúc đơn điệu và đa giác đơn điệu

Trước hết ta quy ước đường thẳng ab là đường thẳng đi qua hai


điểm phân biệt a và b theo hướng ab.
Định nghĩa 1.2.1 (xem [14]) Trong mặt phẳng R2 , cho 3 điểm a(x1 ; y1) ;
b(x2 ; y2 ); c(x3 ; y3 ).
Ký hiệu S(a, b, c) là diện tích đại số của abc, khi đó :

S(a, b, c) =

(x2 − x1 )(y3 − y1 ) − (x3 − x1 )(y2 − y1 )
2


11

=

1 x2 − x1 y2 − y1
2 x3 − x1 y3 − y1

Khi đó ta nói:
• Điểm c gọi là nằm bên trái đường thẳng ab khi và chỉ khi
S(a, b, c) > 0
• Điểm c gọi là nằm bên phải đường thẳng ab khi và chỉ khi
S(a, b, c) < 0
c
b
b
a
a
c nằm bên trái đường thẳng ab

c
c nằm bên phải đường thẳng ab

Hình 1.2: Minh hoạ điểm nằm bên trái, bên phải đường thẳng


Định nghĩa 1.2.2 (xem [14]) Đa giác là một miền mặt phẳng được
giới hạn bởi một đường gấp khúc khép kín những đoạn thẳng trong
mặt phẳng. Những đoạn thẳng gọi là cạnh của đa giác và những điểm
chung của hai đầu đoạn thẳng gọi là đỉnh. Một đa giác gọi là đa giác
đơn nếu các cạnh của nó không giao nhau, nghĩa là hai cạnh kề của
nó chỉ có một điểm chung là đỉnh .
Trong luận văn này chúng tôi chỉ xét những đa giác mà không có bất
kỳ ba đỉnh nào thẳng hàng.
• Một đỉnh của đa giác P được gọi là đỉnh phản xạ (reflex) nếu góc
bên trong của nó lớn hơn Π.
• Một đỉnh của đa giác P được gọi là đỉnh lồi (convex vertex) nếu
góc bên trong của nó nhỏ hơn Π.
Định nghĩa 1.2.3 (xem [13]) Một đường gấp khúc đa giác q1 q2 . . . qk
là một dãy của những điểm qi (i = 1, k) trong mọi cặp nào những điểm


12

kề qi và qi+1 biểu thị một đoạn với i = 1, k − 1 và không có hai đoạn
nào không liên tiếp cắt nhau.

Đa giác đơn

Đa giác
Hình 1.3: Minh hoạ đa giác

Một đa giác đơn chia mặt phẳng ra thành phần trong, biên và phần
ngoài . Giả sử đa giác P = v0 , v1 , . . . , vn−1 . Hai đỉnh không kề nhau vi
và vi−1 với ithì đòi hỏi thêm, đoạn nối hai đỉnh này phải hoàn toàn nằm trong

miền trong của đa giác đơn).
Tam giác phân một đa giác là dùng những đường chéo không giao
nhau của đa giác để chia phần trong của đa giác thành các tam giác.
Định nghĩa 1.2.4 Cho đa giác đơn gồm n+1 đỉnh < p0 , p1 , . . . , pn >.
Khi đó, ta nói thứ tự các đỉnh pi (i = 0, n) của đa giác sắp thứ tự
ngược chiều kim đồng hồ nếu và chỉ nếu tiếp giáp với phần bên trái
cạnh pi pi+1 , ∀i = 0, n − 1 là phần trong đa giác.
Trong trường hợp ngược lại, ta nói các đỉnh pi của đa giác sắp xếp
theo thứ tự cùng chiều kim đồng hồ.
1.2.2

Các tính chất

Bổ đề 1.2.1 (xem [14])
Mọi đa giác đều có ít nhất một đỉnh lồi.
Chứng minh. Giả sử cho đa giác P có các đỉnh sắp thứ tự ngược chiều
kim đồng hồ, L là đường thẳng đi qua một đỉnh v có tung độ thấp nhất


13

v

L

Hình 1.4: Minh hoạ sự tồn tại đỉnh lồi

của P . Nếu có hai đỉnh có cùng tung độ thấp nhất, xét đỉnh v nằm về
phía bên phải. Khi đó phần trong của P phải nằm về phía trên đường
thẳng L do đó cạnh đi sau v cũng phải nằm phía trên L do đó góc trong

tại đỉnh v nhỏ hơn Π.


Bổ đề 1.2.2 (xem [14]) Mọi đa giác n đỉnh, n ≥ 4 có ít nhất một
đường chéo.
Định lý 1.2.1 (xem [14]) Mọi đa giác P n đỉnh có thể phân chia
thành các tam giác bằng việc thêm các đường chéo (có thể bằng không)

b

d

a

Hình 1.5: Minh hoạ tính chất đường chéo

Chứng minh. (minh họa hình 1.5) Ta chứng minh bằng quy nạp:
- Nếu n = 3 thì đa giác là một tam giác (hiển nhiên đúng)
- Nếu n ≥ 4, giả sử d = ab là một đường chéo của P (tồn tại do bổ đề
1.2.2). Vì theo định nghĩa d chỉ cắt biên P tại những điểm cuối, nó


14

phân chia P thành hai đa giác, mỗi đa giác đó nhận d làm một cạnh,
rõ ràng hai đa giác ít hơn n đỉnh và mỗi đa giác ngoài hai đỉnh a, b có
ít nhất một đỉnh khác nữa. Do đó áp dụng giả thiết quy nạp cho hai
đa giác đó ta có điều phải chứng minh.




Mệnh đề 1.2.1 (xem [14]) Mọi phép tam giác phân đa giác n đỉnh
cần sử dụng n − 3 đường chéo trong và chứa n − 2 tam giác.
Chứng minh. Ta chứng minh bằng quy nạp:
- Với n = 3 luôn đúng.
- Giả sử n ≥ 4. Phân chia đa giác P thành hai đa giác P1 và P2
bởi đường chéo d = ab. Giả sử hai đa giác đó lần lượt có số đỉnh
là n1 , n2 . Ta có: n1 + n2 = n + 2 (a, b có trong n1 và n2 . áp dụng
giả thiết quy nạp đối với hai đa giác P1 và P2 , ta thấy có tất cả
(n1 −3)+(n2 −3)+1 = n−3 đường chéo và có (n1 −2)+(n2 −2) = n−2
tam giác.


Hệ quả 1.2.1 Tổng các góc trong một đa giác n đỉnh là (n − 2)Π
Chứng minh. Theo mệnh đề 1.2.1 ta có n − 2 tam giác và mỗi tam giác
có tổng các góc trong là Π nên tổng các góc trong của đa giác n đỉnh
là (n − 2)Π.


Định nghĩa 1.2.5 (xem [14], trang 45)
• Đường gấp khúc C là đường gấp khúc đơn điệu nếu tồn tại một
đườg thẳng L sao cho mọi đường thẳng vuông góc với L thì hoặc
nó không cắt C, hoặc cắt C tại một điểm, hoặc cắt C theo một đoạn
thẳng. Và khi đó ta cũng nói đường gấp khúc C là đơn điệu theo
phương L.
• Một đa giác được gọi là đơn điệu nếu nó là đa giác đơn và biên


15


của nó hợp thành từ hai đường gấp khúc đơn điệu cùng theo một
phương.

C

P
a

L

L

b

Đa giác đơn điệu
Đường gấp khúc đơn điệu
Hình 1.6: Minh hoạ đường gấp khúc đơn điệu và đa giác đơn điệu.

Định nghĩa 1.2.6 (xem [14]) Một đa giác đơn P được gọi là y - đơn
điệu nếu nó đơn điệu đối với trục oy.
Định nghĩa 1.2.7 (xem [14], trang 46) Một đỉnh v của một đa giác
đơn được gọi là đỉnh lùi phía trong (interior cusp) nếu góc bên trong
tại v lớn hơn Π và hai đỉnh kề bên nó có tung độ lớn hơn hoặc nhỏ
hơn tung độ của v.
Mệnh đề 1.2.2 (xem [14], trang 46) Nếu P là một đa giác đơn không
có điểm lùi trong, thì P là một y-đơn điệu.
1.3
1.3.1

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

Khái niệm độ phức tạp của thuật toán

(xem [2]) Độ phức tạp của thuật toán là những thước đo để so sánh
tính hiệu quả của thuật toán. Một thước đo hiệu quả đó là thời gian
máy tính sử dụng để giải bài toán theo thuật toán đang xét, khi các
giá trị đầu vào có một kích thước xác định. Một thước đo thứ hai đó
là bộ nhớ đòi hỏi thực hiện thuật toán đó khi giá trị đầu vào có kích
thước cho trước. Gắn liền với thời gian tính toán của thuật toán là độ
phức tạp thời gian và bộ nhớ là độ phức tạp không gian. Biết được độ


16

phức tạp thời gian cho một thuật toán rất quan trọng, vì khi đó ta
biết được thời gian là một phút, một năm, một tỉ năm để thực hiện
thuật toán đó. Độ phức tạp không gian đòi hỏi của thuật toán mà ta
biết được thì cho ta một bước chuẩn bị và thấy được khả năng đáp
ứng trong việc tính toán của thuật toán.
Độ phức tạp không gian gắn liền với cấu trúc dữ liệu đặc biệt dùng
để tính toán trong thật toán. Trong đề tài này chúng tôi không nghiên
cứu về cơ sở dữ liệu nên ta bỏ qua độ phức tạp không gian.
Để tính toán độ phức tạp của thuật toán ta chỉ xét những hàm thực
f : N −→ R xác định trên tập số nguyên dương và hầu như dương làm
công cụ đo. Nghĩa là tồn tại một số nguyên dương n0 sao cho f (n) > 0
với mọi n > n0 . Kí hiệu F là tập hợp tất cả các hàm như vậy.
1.3.2

Các định nghĩa

(xem [2]) Cho hàm số g(n) ∈ F , ta định nghĩa O g(n) là một

tập hợp tất cả các hàm f (n) ∈ F có tính chất: Tồn tại hằng số c và
n0 sao cho với mọi n > n0 thì f (n)
c.g(n). Nếu f (n) ∈ O g(n) ,
thì ta nói rằng f (n) là Ô lớn của g(n), ( xem hình vẽ 1.7). Những
hàm thuộc O thường dùng như chặn dưới của hàm thực hiện tính
toán trong thuật toán để giải một bài toán. Người ta dùng kí hiệu
y
cg(n)
f (n)

0

n

Hình 1.7: Mô tả quan hệ giữa hai hàm cg(n) và f (n).


17

f (n) = g(n) + O h(n) , nghĩa là
f (n) − g(n) = O h(n) .
Ví dụ: f (n) = 2n3 + 7n2 − 6n + 2, thì ta có thể viết
f (n) = 2n3 + O(n2 ).

Định nghĩa 1.3.1 (xem [2]) Cho hàm số g(n) ∈ F , ta định nghĩa
θ g(n) là tập hợp tất cả các hàm f (n) ∈ F có tính chất: Tồn tại
hằng số dương c1 , c2 và n0 sao cho với mọi n > n0 thì c1 .g(n) ≤
f (n) ≤ c2 .g(n).
Định nghĩa 1.3.2 (xem [2]) Cho hàm số g(n) ∈ F , ta định nghĩa
Ω g(n) là tập hợp tất cả các hàm f (n) ∈ F có tính chất: Tồn tại

hằng số dương c và n0 sao cho với mọi n > n0 thì c.g(n) ≤ f (n).
Nếu f (n) ∈ Ω g(n) , thì ta nói f (n) là Ô mê ga lớn của g(n).
1.3.3

Các tính chất

Mệnh đề 1.3.1 (xem [2]) Nếu f1 (n) ∈ O g1 (n) và f2 (n) ∈ O g2 (n)
thì
f1 (n) + f2 (n) ∈ O g1 (n) + g2 (n) .
Chứng minh. Giả sử rằng với mọi n ≥ n1 , f1 (n) ≤ c1 .g1 (n) và với mọi
n ≥ n2 , f2 (n) ≤ c2 .g2 (n).
Ta đặt n0 = max{n1 , n2 } và c0 = max{c1 , c2 }. Khi đó với mọi n > n0
ta có
f1 (n)+f2 (n) ≤ c1 .g1 (n)+c2 .g2 (n) ≤ c0 .(g1 (n)+g2 (n)).
.
Mệnh đề 1.3.2 (xem [2]) Nếu f1 (n) ∈ O g1 (n) và f2 (n) ∈ O g2 (n)
thì
f1 (n) + f2 (n) ∈ O max{g1 (n), g2 (n)} .


18

Chứng minh. Giả sử rằng với mọi n ≥ n1 , f1 (n) ≤ c1 .g1 (n) và với mọi
n ≥ n2 , f2 (n) ≤ c2 .g2 (n).
Ta đặt n0 = max{n1 , n2 } và c0 = c1 + c2 . Khi đó với mọi n > n0 ta

f1 (n) + f2 (n) ≤ c1 .g1 (n) + c2 .g2 (n) ≤ c0 .(max{g1 (n), g2 (n)}).
⇔ f1 (n) + f2 (n) ∈ O max{g1 (n), g2 (n)} .

Mệnh đề 1.3.3 (xem [2]) Nếu f1 (n) ∈ O g1 (n) và f2 (n) ∈ O g2 (n)

thì
f1 (n).f2 (n) ∈ O g1 (n).g2 (n) .
Chứng minh. Giả sử rằng với mọi n ≥ n1 , f1 (n) ≤ c1 .g1 (n) và với mọi
n ≥ n2 , f2 (n) ≤ c2 .g2 (n).
Ta đặt n0 = max{n1 , n2 } và c0 = c1 .c2 . Khi đó với mọi n > n0 ta có
f1 (n).f2 (n) ≤ c1 .g1 (n).c2 .g2 (n) ≤ c0 .(g1 (n).g2 (n)).

Mệnh đề 1.3.4 (xem [2]) Cho P (n) = ak nk + ak−1 nk−1 + ... + a1 n + a0
là đa thức bậc k, ak > 0. Khi đó P (n) ∈ O(nk ).
Chứng minh. Do ta có: P (n) = ak nk + ak−1 nk−1 + ... + a1 n + a0
≤ ak nk + | ak−1 | nk−1 + ...+ | a1 | n+ | a0 |
≤ | ak | nk + | ak | nk + ...+ | a1 | nk + | a0 | nk .
= (| ak | + | ak−1 | +...+ | a1 | + | a0 |)nk
Nếu c =| ak | + | ak−1 | +...+ | a1 | + | a0 |, thì P (n) ≤ c.nk với mọi
n > n0 = 1. Vậy P (n) ∈ O(nk ).


19

1.3.4

Cách tính độ phức tạp của thuật toán

Độ phức tạp tính toán được đo bằng hàm O(...) là chính. Vì vậy để
tính độ phức tạp tính toán của thuật toán tức là ta đi xác định hàm
T (n) ∈ O(g(n)) cho đoạn mã chương trình đó, n là biến số của phép
toán cơ sở .
Các phép toán được dùng để đo độ phức tạp thời gian có thể là
phép so sánh các số nguyên, phép cộng, phép trừ, nhân, chia các số
nguyên hoặc bất kì một phép toán sơ cấp nào khác.

1.3.5

Phép tính cơ sở

(Xem[2]) Độ phức tạp của toán tử cơ sở là một hằng số, nghĩa là
O(1). Toán tử cơ sở là gì không phải dễ xác định, với nhũng bắt buộc
khác nhau cho ta định nghĩa lại phép toán cơ sở. Theo nguyên tắc,
phép toán cơ sở là phép toán thực hiện một hằng số thời gian, phụ
thuộc vào dung lượng thao tác trên thông tin. Thường thường phép
tính cơ sở là các phép tính cộng, trừ, nhân, chia . . . Nhưng chú ý rằng
khi ta thực hiện số lớn hàng tỉ thì không thể chấp nhận phép nhân
các số lớn là một phép tính cơ sở. Cũng không thể nhận phép tính cơ
sở là các hàm lượng giác, hàm số mũ, hàm số lôgarit, . . . bởi vì chúng
tính toán theo dãy.
1.3.6

Dãy các phép tính

(Xem[2]) Độ phức tạp thời gian của dãy liên tiếp các phép tính xác
định bởi độ phức tạp cao nhất trong chúng.
Tức là, giả sử toán tử s1 có độ phức tạp F1 , s2 có độ phức tạp F2 .
Khi đó:
T (s1 ) ∈ O(F1 ), T (s2 ) ∈ O(F2 ) ⇒ T (s1 , s2 ) ∈ max{O(F1 ), O(F2 )}.
Để dễ dàng cho việc phân tích thuật toán ta kết hợp những kí hiệu
độ đo phức và phân tích trong trường hợp xấu nhất để biết được


20

thời gian thực hiện những thuật toán trong thời gian xấu nhất là bao

nhiêu? Người ta định ra độ phức tạp của các phép toán trong trường
hợp xấu nhất là:
1. Phép gán có độ phức tạp O(1).
2. Phép nhập vào thủ tục có độ phức tạp O(1).
3. Phép ra khỏi thủ tục có độ phức tạp O(1).
4. Mệnh đề if<điều kiện> độ phức tạp là thời gian so sánh
cộng với O(max của hai nhánh).
5. Vòng (While) có độ phức tạp là tổng tất cả các vòng lặp với
thời gian của mỗi vòng lặp đó.
Ví dụ 1.3.1 (xem [2])
Xét đoạn chương trình tính tổng sau:
1. n := 100
2. sum := 0
3. for i := 1 to n do;
4.

for j := 1 to n do;

5.
6.

sum := sum + 1;
end for;

7. end for;
Ta phân tích đoạn chương trình trên. Dòng số 1 và 2 cố định mất thời
gian hằng số, ta kí hiệu là a. Cho ta phép tính toán ở dòng 3 gồm
i := 1, kiểm tra i < n và i := i + 1 cũng chiếm thời gian hằng số, ta
kí hiệu lần lượt là b, c, d. Tương tự ở dòng 4 thời gian cho các phép
toán j := 1; j < n và j := j + 1 cũng chiếm thời gian hằng số, ta kí

hiệu lần lượt là e, f, g. Cuối cùng phép toán ở dòng 5 đòi hỏi thời gian
hằng số là h.
Với những đại lượng ở trên thì không khó tính được thời gian chung
cho thực hiện đoạn chương trình với giá trị bất kì n nào đó:
T (n) = a + b + nc + nd + n(e + nf + ng + nh)


21

= a + b + nc + nd + ne + n2 f + n2 g + n2 h
= n2 (f + g + h) + n(c + d + e) + a + b
Bởi vì a, b, c, e, g, f, h là những hằng số, ta đặt:
i = f + g + g, j = c + d + e, k = a + b
Khi đó thuật toán thực hiện mất thời gian là
T (n) = i.n2 + j.n + k
Vậy T (n) = O(n2 ).
Ví dụ 1.3.2 độ phức tạp của vòng for của đoạn chương trình sau
(Xem[2])
1: fact := 1;
2: for i := 1 to n do
3:
fact := fact + i;
4: end for
Dòng 1: phép tính cố định mất thời gian hằng số, kí hiệu là a.
Dòng 2: Với phép toán gán i := 1, kiểm tra i < n và i := i + 1 cũng
chiếm thời gian hằng số, ta kí hiệu lần lượt là b, c, d.
Dòng 3: Cũng đòi hỏi thời gian hằng số, kí hiệu là e.
Khi đó, thời gian (độ phức tạp) để thực hiện chương trình là:
T (n) = a + b + n(c + d) + n(e) = n(c + d + e) + a + b
Suy ra T (n) = O(n).

Ví dụ 1.3.3 Tìm độ phức tạp của cấu trúc if(p) then s1 ; else s2
(xem [2])
Nếu độ phức tạp của p, s1 , s2 tương ứng là O(P ), O(F1 ), O(F2 ) thì độ
phức tạp của cấu trúc if là max{O(P ), O(F1 ), O(F2 )}, nghĩa là độ
phức tạp tăng nhanh nhất của hàm P, F1 , F2 .
T (P ) ∈ O(P ); T (s1 ) ∈ O(F1 ); T (s2 ) ∈ O(F2 ).


22

Suy ra T (if(p) then s1 else s2 ) ∈ max{O(P ), O(F1 ), O(F2 )}.
Ta có thể giải thích như sau:
- Giả sử điều kiện p đúng thì dãy lệnh p, s1 được thực hiện có độ phức
tạp là max{O(P ), O(F1 )}.
- Giả sử điều kiện p sai thì dãy lệnh p, s2 được thực hiện có độ phức
tạp là max{O(P ), O(F2 )}.
Mà ta chưa biết trong hai khối lệnh thì khối nào thực hiện trước. Do
đó, ta nhận được độ phức tạp cho toàn vòng if là
T (if(p) then s1 else s2 ) ∈
max{max{O(P ), O(F1 )}; max{O(P ), O(F2 )}}
= max{O(P ), O(F1 ), O(F2 )}.
1.4

Thuật toán tìm tiếp tuyến của O’Rourke

Bài toán: Trong mặt phẳng cho đa giác lồi P có n đỉnh, giả sử số
đỉnh là {p0 , p1 , .., pn−1 } được đánh số theo thứ tự ngược chiều kim đồng
hồ và p là một điểm nằm ngoài P. Hãy tìm thuật toán xác định đường
thẳng tiếp tuyến từ p tới P.
Mô tả thuật toán(xem [14]).

Để tìm hai tiếp tuyến ta bắt đầu với việc tìm hai tiếp điểm. Việc
tìm hai tiếp điểm được thực hiện như sau:
Giả sử tại điểm thứ pi nếu điểm p nằm bên trái của pi−1 pi và p nằm
bên phải của pi pi+1 thì pi là tiếp điểm của tiếp tuyến trái. Giả sử tại
điểm thứ pj nếu điểm p nằm bên phải của pi−1 pi và p nằm bên trái
của pj pj+1 thì pj là tiếp điểm của tiếp tuyến phải kẻ được từ điểm p
tới P. Để đơn giản hơn trong việc đưa ra thuật toán ta có thể cải tiến
thuật toán như sau:
Tìm điểm pi sao cho hai điểm pi−1 , pi+1 đều nằm bên phải ppi thì
ppi là tiếp tuyến bên trái của P. Ngược lại, nếu có điểm pi sao cho hai


23
right
pj
pj+1

left

pj−1
p
right

Q
pi+1
pi−1

pi

left


Hình 1.8: Minh hoạ thuật toán tìm tiếp tuyến

điểm pi−1 , pi+1 đều nằm bên trái ppi thì ppi là tiếp tuyến bên phải của
P.
Thuật toán 1.4.1
for i = 1 to n do
if pi−1 , pi+1 nằm bên phải ppi then
ppi là tiếp tuyến bên trái end if,
if pi−1 , pi+1 nằm bên trái ppi then
ppi là tiếp tuyến bên phải end if,
end for.
Độ phức tạp của thuật toán
Do thuật toán trên sử dụng vòng for nên có độ phức tạp là tuyến
tính O(n) (theo cách xác định độ phức tạp của vòng for ở ví dụ 1.3.2).


Chương 2

Thuật toán Dijkstra và thuật toán
tam giác phân đa giác
Trong chương này chúng tôi trình bày các thuật toán: thuật toán
Dijkstra, thuật toán phân chia đa giác thành các đa giác y - đơn điệu,
thuật toán tam giác phân đa giác y - đơn điệu, thuật toán tam giác
phân đa giác đơn và xem như là những chương trình con của thuật
toán chính về tìm đường đi ngắn nhất giữa hai điểm trong một đa giác
đơn ở chương 3.
2.1

Thuật toán Dijstra


Bài toán 2.1.1 Cho đồ thị có trọng số G = (V, E) và hai đỉnh a, b ∈
G. Hãy tìm đường đi có trọng số bé nhất (nếu có) đi từ đỉnh a đến
đỉnh b.
2.1.1

Thuật toán Dijkstra

Năm 1959 Dijkstra đưa ra một thuật toán rất hiệu quả giải bài toán
đường đi ngắn nhất giữa hai đỉnh trong đồ thị. Thuật toán thực hiện
việc gán và giảm giá trị nhãn d(i) tại mỗi đỉnh i của đồ thị G. Thuật
toán được mô tả như sau:
1. Với đỉnh xuất phát a, gán nhãn d(a) := 0.
24


25

2. Nếu có cạnh (i, j) mà đỉnh i đã được gán nhãn và đỉnh j chưa được
gán nhãn hoặc đỉnh j đã được gán nhãn nhưng d(i)+l(i, j) < d(j)
thì giảm nhãn d(j) := d(i) + l(i, j).
3. Lặp lại bước 2 cho đến khi không gán hoặc giảm nhãn được nữa.
Định lý 2.1.1 (xem [4]) Tại mỗi đỉnh b giá trị gán nhãn d(b) cuối
cùng (nếu có) chính là độ dài của đường đi ngắn nhất từ đỉnh a đến
đỉnh b.
Chứng minh. Sau khi thực hiện xong thuật toán trên, nếu giá trị nhãn
d(b) xác định thì ta có đường đi từ đỉnh a đến đỉnh b.
Ta khôi phục đường đi từ a đến b như sau:
Xuất phát từ đỉnh b, tìm cạnh có đỉnh cuối là b và đỉnh đầu là i sao
cho:

d(i) + l(i, b) = d(b)
Đỉnh i như thế luôn tồn tại vì xảy ra đẳng thức ở lần gán hoặc giảm
giá trị nhãn d(j) cuối cùng. Cứ tiếp tục như thế cho đến khi gặp đỉnh
a. Giả sử ta nhận được dãy các cạnh
(a, a1 ), (a1 , a2 ), . . . , (ak−1 , b)
mà trên đó:
d(a) + l(a, a1 ) = d(a1 )
d(a1 ) + l(a1 , a2 ) = d(a2 )
.........................................
d(aak−1 ) + l(ak−1 , b) = d(b)
Cộng từng vế và khử các giá trị chung ở cả hai vế ta có:
l(a, a1 ) + l(a1 , a2 ) + . . . + l(ak−1 , b) = d(b)
Vậy giá trị nhãn d(b) chính là độ dài đường đi nói trên.
Bất kỳ đường đi nào khác từ đỉnh a đến đỉnh b cũng có các hệ thức


×