Tải bản đầy đủ (.doc) (19 trang)

Tiểu luận môn học THIẾT KẾ VÀ PHÂN TÍCH THUẬT TOÁN CÂY KHUNG NHỎ NHẤT

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 (692.43 KB, 19 trang )

Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Cây khung nhỏ nhất
Trong bảng thiết kế mạch điện, việc nối các pin với nhau để chúng tương đương với
nhau về điện thế bằng cách mắc các dây điện với nhau là một bài toán thiết yếu. Để kết
nối một tập gồm n pin, ta có thể sử dụng một cách sắp xếp n-1 dây, mỗi dây kết nối hai
pin với nhau. Trong tất cả các cách sắp xếp, vấn đề đặt ra là tìm cách sắp xếp sao cho
lượng dây sử dụng là ít nhất.
Ta có thể mô hình hoá bài toán bằng một đồ thị liên thông vô hướng G=(V,E) với V
là tập các đỉnh ứng với các pin, E là tập các cạnh ứng với các dây nối giữa các pin, và
mỗi cạnh (u,v) ∈ E, trọng số w(u,v) thể hiện chi phí (lượng dây cần thiết) để nối u và v.
Vấn đề đặt ra là tìm được một tập T⊆ E bao gồm các cạnh không tạo thành chu trình
sao cho tổng trọng số w(T)= là nhỏ nhất. Bởi vì tập các cạnh trong T không tạo
thành chu trình và nối với tất cả các đỉnh của đồ thị, do đó T tạo thành một cây mà ta gọi
là cây khung bao trùm đồ thị G. Ta gọi bài toán xác định T là bài toán tìm cây khung nhỏ
nhất. Hình vẽ 23.1 là ví dụ cây khung nhỏ nhất của đồ thị liên thông.
Trong chương này, ta sẽ nghiên cứu hai thuật toán để giải quyết bài toán cây khung
nhỏ nhất: thuật toán Kruskal và Prim. Thời gian thực hiện của mỗi thuật toán là O(E lg
V) sử dụng đống nhị phân thông thường. Bằng cách sử dụng thuật toán vun đống
Fibonacci, thuật toán Prim có thể cải tiến được thời gian thực hiện là O(E+V lg V), đây là
sự cải tiến trong trường hợp [V] nhỏ hơn nhiều so với [E]
Hai thuật toán Kruskal và Prim là các thuật toán tham lam, thuật toán tham lam được
mô tả ở chương 16. Ở mỗi bước của thuật toán, ta có thể có nhiều sự lựa chọn khác nhau.
Phương pháp “tham lam” đưa ra cách lựa chọn tốt nhất tại thời điểm đang xét. Nhưng xét
một cách tổng quát phương pháp tham lam không đảm bảo tìm ra các giải pháp tối ưu
cho các bài toán. Tuy nhiên đối với bài toán cây khung nhỏ nhất, ta có thể chứng minh
phương pháp tham lam chắc chắn đưa ra một cây khung có trọng số nhỏ nhất. Mặc dù
chương này có thể độc lập với chương 16, nhưng phương pháp tham lam thể hiện ở đây
là một ứng dụng kinh điển của các khái niệm lý thuyết đã được giới thiệu ở chương 16.
Trang 1
Σw(u,v)
(u,v) Є T


2
1
4
6
7
8
2
14
4
10
9
a
b
h
c
g
d
f
e
i
7
11
8
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Hình 23.1 Cho một cây khung nhỏ nhất của đồ thị liên thông. Mỗi cạnh được biểu diễn bới
một trọng số và các cạnh của cây khung nhỏ nhất là các cạnh được tô bóng . Tổng trọng số của
cây khung này là 37. Cây khung nhỏ nhất này là không duy nhất: xoá cạnh (b,c) và thay nó
thành cạnh (a,h) ta vẫn nhận được cây khung khác có trọng số 37.
Phần 23.1 giới thiệu một thuật toán cây khung nhỏ nhất tổng quát để phát triển cây
khung nhỏ nhất bằng cách tại một thời điểm ta bổ sung một cạnh. Phần 23.2 đưa ra hai

cách để thực hiện thuật toán tổng quát. Thuật toán đầu tiên là thuật toán Kruskal là tương
đương với thuật toán các thành phần liên thông ở phần 21.1. Thuật toán thứ hai là thuật
toán Prim tương tự với thuật toán tìm đường đi ngắn nhất Dijkstra(phần 24.3).
23.1 Phát triển cây khung nhỏ nhất
Giả sử cho một đồ thị liên thông vô hướng G=(V,E) và một hàm trọng số w: E R,
ta muốn tìm cây khung nhỏ nhất cho đồ thị G. Hai thuật toán ta sẽ nghiên cứu trong
chương này sử dụng phương pháp tham lam cho bài toán cây khung nhỏ nhất, tuy nhiên
hai thuật toán khác nhau ở điểm làm thế nào để ứng dụng phương pháp tham lam vào
mỗi thuật toán.
Thuật toán tổng quát sau được giải quyết bằng phương pháp tham lam để phát triển
cây khung nhỏ nhất đối với một cạnh tại một thời điểm. Thuật toán quản lý một tập các
cạnh A duy trì tính bất biến của vòng lặp sau.
Trước mỗi bước lặp, A là tập con của cây khung nhỏ nhất nào đó
Ở mỗi bước, ta xác định một cạnh (u,v) có thể được bổ sung vào A nhưng không phá
vỡ tính chất bất biến của tập A, điều đó có nghĩa là A U {(u,v)} vẫn là tập con của cây
khung nhỏ nhất. Ta gọi cạnh như vậy là cạnh an toàn cho A, bởi vì cạnh này có thể được
bổ sung một cách an toàn vào A nhưng vẫn duy trì được tính chất của A.
GENERIC – MST (G,w)
1 A Ø
2 while A does not form a spanning tree
3 do find an edge (u,v) that is safe for A
4 AAU{(u,v)}
5 return A
Ta sử dụng vòng lặp bất biến như sau:
Ban đầu: Trong khi A chưa tạo thành cây khung nhỏ nhất.
Trang 2
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Duy trì: Vòng lặp từ dòng 2 đến 4 duy trì tính chất của A bằng cách chỉ bổ sung các
cạnh an toàn vào tập A.
Kết thúc: Tất cả các cạnh bổ sung vào tập A là cây khung nhỏ nhất. Tập A được trả

về là một cây khung nhỏ nhất.
Tuy nhiên, việc xác định một cạnh an toàn ở dòng 3 là một vấn đề không đơn giản.
Sự tồn tại của một cạnh an toàn là chắc chắn bởi vì khi thực hiện dòng thứ 3 của thuật
toán, tính bất biến sẽ dẫn đến sự tồn tại một cây khung T sao cho A⊆ T. Trong vòng lặp
while, A phải là tập con thực sự của T vì vậy nếu cạnh (u,v)∈T mà (u,v)∉A thì (u,v) là
an toàn của A.
Trong phần còn lại của phần này, ta đưa ra một quy tắc (Định lý 23.1) để nhận biết
các cạnh an toàn. Phần tiếp theo mô tả hai thuật toán sử dụng nguyên tắc này để tìm ra
các cạnh an toàn một cách hiệu quả.
Đầu tiên ta cần định nghĩa một số khái niệm sau, một phép cắt (S,V-S) của đồ thị vô
hướng G=(V,E) là một phân chia của V. Hình 23.2 là ví dụ minh họa của phép cắt (S,V-
S). Ta nói một cạnh (u,v) ∈ E xuyên qua phép cắt (S,V-S) nếu có đỉnh cuối thuộc S và
đỉnh còn lại thuộc V-S. Một phép cắt bảo toàn tập các cạnh A nếu không có cạnh nào của
A xuyên qua phép cắt. Một cạnh là được gọi là cạnh nhẹ (light edge) xuyên qua phép cắt
nếu trọng số của nó là nhỏ nhất trong mọi trọng số của các cạnh xuyên qua phép cắt. Lưu
ý rằng có thể có nhiều hơn một cạnh nhẹ xuyên qua một phép cắt trong trường hợp liên
kết. Thông thường, một cạnh là một cạnh nhẹ thoả mãn một tính chất nào đó nếu trọng số
của cạnh đó là nhỏ nhất của tất cả các cạnh thoả mãn tính chất đó. Nguyên tắc để nhận
biết các cạnh an toàn cho bởi định lý sau:
Định lý 23.1
Cho G=(V,E) là một đồ thị liên thông, vô hướng với hàm trọng số w định nghĩa trên
E. Cho A là tập con của E gồm các cây khung nhỏ nhất của G, cho (S, V-S) là phép cắt
bất kỳ của đồ thị G và bảo toàn tập các cạnh A, đặt (u,v) là cạnh nhẹ (light edge) xuyên
qua (S,V-S). Vậy cạnh (u,v) là cạnh an toàn của A .
Chứng minh. Cho T là một cây khung nhỏ nhất chứa tập A, giả sử T không chứa cạnh
nhẹ (u,v) , bởi vì nếu T chứa cạnh nhẹ điều đó có nghĩa ta chứng minh xong. Ta sẽ xây
dựng cây khung nhỏ nhất khác T’ mà chứa AU{(u,v)} bằng cách sử dụng kỹ thuật cắt
dán, do đó ta có (u,v) là một cạnh an toàn của A.
Trang 3
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6

(a)
(b)

Hình 23.2 Hai hình vẽ trên là phép cắt (S,V-S) của đồ thị ở hình 23.1 (a) Các đỉnh thuộc tập
S được tô màu đen, và các đỉnh thuộc tập V-S là màu trắng. Các cạnh xuyên qua phép cắt là sự
kết nối giữa các đỉnh trắng và đỉnh đen. Cạnh (d,c) là cạnh nhẹ duy nhất đi qua phép cắt. Tập
con A bao gồm các cạnh được tô bóng lưu ý ở đây phép cắt (S,V-S) là phép cắt bảo toàn các
cạnh A bởi vì không có cạnh nào của A xuyên qua phép cắt. (b) đối với đồ thị ở hình (a) các
đỉnh trong tập S ở bên trái và các đỉnh trong tập V-S ở bên phải. Một cạnh xuyên qua phép cắt
nếu nó nối một đỉnh bên trái và một đỉnh bên phải.
Cạnh (u,v) biểu diễn một chu trình bao gồm các cạnh trên đường dẫn p từ u tới v
trong T, như minh họa ở hình 23.3. Bởi vì u và v là các đỉnh đối nhau của phép cắt
Trang 4
a
b
d
e
1
4
6
7
8
2
14
4
10
9
h
c
g

f
i
2
7
11
8
S
V-S
d
e
a
b
c
f
4
9
8
7
14
10
h
g
i
6
4
7
11
8
2
1

2
S
V-S
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
(S,V-S), do đó có ít nhất một cạnh trong T trên đường dẫn p cũng xuyên qua phép cắt.
Cho (x,y) là cạnh bất kỳ thoả mãn các tính chất trên. Cạnh (x,y) không thuộc A do phép
cắt bảo toàn các cạnh của tập A. Bởi vì (x,y) nằm trên đường dẫn duy nhất từ u đến v
trong T, xoá (x,y) tách T thành hai phần. Thêm (u,v) tạo thành một cây khung mới T’ =T-
{(x,y)}U {(u,v)}.
Ta tiếp tục biểu diễn T’ là cây khung nhỏ nhất. Bởi vì (u,v) là cạnh nhẹ xuyên qua
(S,V-S) và (x,y) cũng xuyên qua phép cắt do đó w(u,v)≤w(x,y) . Vì vậy:
w(T’) = w(T) - w(x,y) + w(u,v)
≤ w(T)
Do T là cây khung nhỏ nhất, vì vậy mà w(T)≤w(T’). Vì vậy T’ cũng là cây khung
nhỏ nhất.
Hình 23.3 Chứng minh định lý 23.1 Các đỉnh thuộc S là màu đen và các đỉnh thuộc V-S là
màu trắng. Ta biểu diễn các cạnh trong cây khung nhỏ nhất T nhưng không biểu diễn các cạnh
trong đồ thị G. Các cạnh trong A được tô bóng và (u,v) là cạnh nhẹ xuyên qua phép cắt (S,V-S).
Cạnh (x,y) là cạnh trên đường dẫn duy nhất p từ u đến v trên T. Cây khung nhỏ nhất T’ chứa
(u,v) và được thiết lập bằng cách xoá cạnh (x,y) từ T và thêm cạnh (u,v).
T’ vẫn duy trì được (u,v) là cạnh an toàn của tập A. Ta có A⊆T’ bởi vì A⊆ T và (x,y)
⊈ A ; vì vậy A⋃{(u,v)} ⊆ T'. Do đó T’ là cây khung nhỏ nhất, và (u,v) là cạnh an toàn
của A.
Định lý 23.1 giúp ta hiểu rõ cách thức thực hiện thuật toán GENERIC-MST trên đồ
thị liên thông G=(V,E). Khi thuật toán bắt đầu thực hiện, A là tập các cạnh không tạo
thành chu trình nếu không thì cây khung nhỏ nhất chứa A sẽ chứa một chu trình, điều
này dẫn đến mâu thuẫn. Ớ bất kỳ thời điểm nào khi thực hiện thuật toán, đồ thị
G
A
=(V,A) là rừng và mỗi thành phần liên thông của G

A
là một cây. (Một số cây có thể chỉ
Trang 5
u
x
y
v
p
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
chứa một đỉnh, ví dụ khi thuật toán bắt đầu thực hiện: A là tập rỗng và rừng chứa [V]
cây, mỗi cây cho mỗi đỉnh). Hơn thế nữa, bất kỳ cạnh an toàn (u,v) thuộc A nối với các
thành phần phân biệt của G
A
, bởi vì A⋃{(u,v)} phải là tập các cạnh không tạo thành chu
trình.
Vòng lặp từ dòng 2 – 4 của GENERIC MST được thực hiện [V] –1 lần ứng với mỗi
[V]-1 cạnh của cây khung nhỏ nhất lần lượt được xác định thành công. Ban đầu khi
A=∅, có [V] cây trong G
A
, và số vòng lặp giảm xuống 1. Khi rừng chỉ chứa một cây duy
nhất thì thuật toán kết thúc. Hai thuật toán trong phần 23.2 sử dụng hệ quả của định lý
23.1.
Hệ quả 23.2
Cho G=(V,E) là một đồ thị liên thông, vô hướng với hàm trọng số w định nghĩa trên
E. Cho A là một tập con của E bao gồm một số cây khung nhỏ nhất cho đồ thị G, và cho
C=(V
C
,E
C
) là một thành phần liên thông (cây) trong rừng G

A
=(V,A). Nếu (u,v) là cạnh
nhẹ nối C với vài thành phần khác trong G
A
, thì (u,v) là cạnh an toàn của A.
Chứng minh Phép cắt (V
C
,V-V
C
) bảo toàn các cạnh của tập A, và (u,v) là một cạnh
nhẹ qua phép cắt này. Vì thế (u,v) là cạnh an toàn của A.
Bài tập
23-1-1
Đặt (u,v) là cạnh có trọng số nhỏ nhất của đồ thị G. Chứng tỏ rằng (u,v) thuộc vào một
cây khung nhỏ nhất nào đó của G.
23-1-2
Giáo sư Sabatier đưa ra định lý đảo của định lý 23.1 như sau: đặt G = (V, E) là một đồ
thị liên thông và vô hướng với một hàm trọng số giá trị thực w định nghĩa trên E. Đặt A
là một tập con của E thuộc vào một cây khung nhỏ nhất nào đó của G, đặt (S, V-S) là
phép cắt bất kỳ của G bảo toàn các cạnh của tập A, và đặt (u, v) là một cạnh an toàn của
A xuyên qua phép cắt (S, V-S). Do đó, (u,v ) là một cạnh nhẹ thuộc vào phép cắt. Chứng
minh rằng giả định của giáo sư Sabatier là không đúng bằng cách đưa ra một phản chứng.
23-1-3
Chứng minh rằng nếu một cạnh (u,v) thuộc vào một cây khung nhỏ nhất nào đó thì nó
là một cạnh nhẹ (light) xuyên qua phép cắt của đồ thị.
23-1-4
Trang 6
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Cho một ví dụ đơn giản về một đồ thị liên thông sao cho với một tập cạnh (u,v): {Tồn
tại một phép cắt (S, V-S) sao cho (u, v) là một cạnh nhẹ xuyên qua (S, V-S)} không tạo

thành một cây khung nhỏ nhất.
23-1-5
Cho e là một cạnh trọng số nhỏ nhất trên một chu trình nào đó của đồ thị liên thông
G= (V,E). Chứng minh rằng có một cây khung nhỏ nhất của G’=(V, E-{e}) đồng thời là
cây khung nhỏ nhất của G. Tức là có một cây khung nhỏ nhất của G mà nó không chứa e.
23-1-6
Chứng minh rằng có một đồ thị có duy nhất một cây khung nhỏ nhất nếu với mỗi phép
cắt của đồ thị, có một cạnh nhẹ duy nhất đi qua phép cắt. Chứng tỏ rằng điều ngược lại
không đúng bằng cách đưa ra một phản chứng.
23-1-7
Giả sử rằng nếu mọi cạnh của một đồ thị đều có trọng số là số dương thì bất kì tập con
của tập cạnh nối tấ cả các đỉnh có tổng trọng số nhỏ nhất phải là một cây. Cho một ví dụ
để chứng tỏ rằng kết luận tương tự không đúng nếu chúng ta cho phép một vài trọng số
không phải là số dương.
23-1-8
Đặt T là một cây khung nhỏ nhất của đồ thị G và L là một danh sách sắp xếp các trọng số
cạnh của T. Chứng tỏ rằng với bất kì cây khung nhỏ nhất khác T’ của G thì danh sách L
cũng là danh sách sắp xếp các trọng số của các cạnh của T’.
23-1-9
Đặt T là một cây khung nhỏ nhất của đồ thị G = (V, E), và đặt V’ là một tập con của V.
Đặt T’ là đồ thị con của T tạo thành từ V’, và đặt G’ là đồ thị con của G tạo thành từ V’.
Chứng tỏ rằng nếu T’ là liên thông thì T’ là một cây khung nhỏ nhất của G’.
23-1-10
Cho một đồ thị G và một cây khung nhỏ nhất T, giả sử rằng ta giảm trọng số của một
trong các cạnh của T. Chứng tỏ rằng T vẫn là cây khung nhỏ nhất của G. Tổng quát hơn,
đặt T là một cây khung nhỏ nhất của G với các trọng số cạnh được cho bởi hàm trọng số
w. Chọn một cạnh (x, y)

T và một số dương k, và định nghĩa hàm trọng số w’ bằng:
w’(u,v) =

Chứng minh rằng T là một cây khung nhỏ nhất của G với các trọng số cạnh cho bởi w’.
23-1-11
Cho một đồ thị G và một cây khung nhỏ nhất T, giả sử rằng chúng ta giảm trọng số của
một trong các cạnh không thuộc T. Cho một thuật toán để tìm ra cây khung nhỏ nhất
trong đồ thị bị thay đổi.
Trang 7
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
23.2 Thuật toán Kruskal và Prim
Hai thuật toán cây khung nhỏ nhất được mô tả trong phần này là sự mở rộng của thuật
toán tổng quát. Mỗi thuật toán sử dụng những quy tắc riêng để xác định một cạnh an toàn
ở dòng thứ 3 của thủ tục GENERIC-MST. Trong thuật toán Kruskal thì A tạo nên một
rừng. Một cạnh an toàn được bổ sung vào tập A thì cạnh đó luôn là cạnh có trọng số nhỏ
nhất trong đồ thị nối hai thành phần phân biệt. Trong thuật toán Prim, A tạo nên một cây
duy nhất trong suốt quá trình thực hiện thuật toán. Cạnh an toàn được bổ sung vào A
luôn là cạnh có trọng số nhỏ nhất nối cây với một đỉnh không thuộc cây.
Trang 8
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Hình 23.4: Thực hiện thuật toán Kruskal đối với đồ thị được mô tả ở hình 23.1. Những cạnh
được tô đậm thuộc rừng A đang được trồng. Thuật toán Kruskal quan tâm đến những cạnh được
sắp xếp theo thứ tự của trọng số. Một mũi tên chỉ đến một cạnh là một bước của thuật toán. Nếu
một cạnh nối hai cây phân biệt trong rừng thì cạnh đó được bổ sung vào rừng, sau đó hợp hai
cây đó thành một cây.
Thuật toán Kruskal
Thuật toán Kruskal dựa trên thuật toán cây khung nhỏ nhất tổng quát được đưa ra ở
phần 23.1. Thuật toán này tìm một cạnh an toàn để phát triển rừng bằng cách tìm trong
tất cả các cạnh (u,v) cạnh nào có trọng số nhỏ nhất nối hai cây bất kỳ trong rừng. Ví dụ
C1 và C2 là hai cây được nối với nhau bởi cạnh (u,v). Bởi vì cạnh (u,v) phải là cạnh nhỏ
nhất nối C1 với cây nào đó, thì theo hệ quả 23.2 thì (u,v) là một cạnh an toàn cho C1.
Thuật toán Kruskal là một thuật toán tham lam với vì ở mỗi bước của thuật toán bổ sung
vào rừng một cạnh có trọng số nhỏ nhất.

Cách thực hiện thuật toán Kruskal được xem như là thuật toán dùng để tính toán các
thành phần liên thông ở phần 21.1. Thuật toán này sử dụng cấu trúc dữ liệu rời nhau để
Trang 9
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
duy trì các tập phần tử rời nhau. Mỗi tập bao gồm các đỉnh của một cây của rừng hiện
thời. Hàm FIND-SET(u) trả về một phần tử đại diện từ tập chứa đỉnh u. Vì vậy, ta xác
định hai đỉnh bất kỳ u và v thuộc về cùng một cây hay không bằng cách kiểm tra hai hàm
FIND-SET(u) va FIND-SET(v) có bằng nhau hay không. Việc hợp cây được hoàn thành
bởi thủ tục UNION.
MST-KRUSKAL(G, w)
1. A ∅
2. for each vertex v∈V[G]
3. do MAKE-SET(v)
4. sort the edges of E into nondecreasing order by weight w
5. for each edge(u,v) ∈ E, taken in nondecreasing order by weight
6. do if FIND-SET(u) ≠ FIND-SET(v)
7. then A  A ∪{(u,v)}
8. UNION(u,v)
9. return A
Thuật toán Kruskal thực hiện như mô tả ở hình 23.4. Ban đầu từ dòng 1- 3 tập A là
tập rỗng và khởi tạo |V| cây và mỗi cây chứa một đỉnh. Các cạnh trong tập E được sắp
xếp theo thứ tự không giảm của trọng số ở dòng 4. Vòng lặp For từ dòng 5-8 làm nhiệm
vụ kiểm tra đối với mỗi cạnh (u,v) cho dù các đỉnh cuối u và v có thuộc cùng một cây
hay không. Nếu u và v thuộc cùng một cây thì cạnh (u,v) không thể bổ sung vào rừng , vì
cạnh (u,v) sẽ tạo thành chu trình do đó ta loại bỏ cạnh (u,v). Thay vào đó, hai đỉnh thuộc
về hai cây khác nhau trong trường hợp này cạnh (u,v) được bổ sung vào tập A ở dòng 7
và hai cây đó được hợp thành một cây ở dòng 8.
Thời gian thực hiện thuật toán Kruskal cho đồ thị G=(V,E) phụ thuộc vào việc thực
hiện của cấu trúc dữ liệu của tập rời nhau. Ta giả sử rằng việc thực hiện rừng tập tách rời
(disjoin-set-forest) trong phần 21.3 với việc hợp theo thứ hạng (union-by-rank) và nén

đường dẫn (path-compression) mang tính kinh nghiệm bởi vì nó gần như biết được cách
thực hiện nhanh nhất. Ban đầu tập A ở dòng 1 thời gian thực hiện mất 0(1) và thời gian
để thực hiện sắp xếp các cạnh ở dòng 4 là 0(E lg E) (Ta sẽ tính toán chi phí |V| lần thao
tác MAKE-SET trong vòng lặp For ở dòng 2 và 3 cùng một lúc). Vòng lặp For ở dòng 5-
8 thực hiện 0(E) thao tác FIND-SET và UNION trên rừng tập tách rời. Đối với |V| thao
tác MAKE-SET thì tổng thời gian thực hiện là 0((V+E)α(V)) trong đó α là hàm phát triển
chậm được định nghĩa ở phần 21.4. Bởi vì đồ thị G đã cho là đồ thị liên thông do đó ta
có|E| ≥|V| -1 do đó thao tác thực hiện trên các tập rời nhau sẽ mất 0(Eα(V)). Mặt khác,
bởi vì α(|V|)=0(lgV)=0(lgE) do đó tổng thời gian thực hiện thuật toán Kruskal là 0(E lg
Trang 10
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
E). Ta nhận thấy |E| <|V|
2
nên ta có lg|E| =0(lg V) hay nói cách khác thời gian thực hiện
thuật toán Kruskal là O(ElgV).
Thuật toán Prim
Tương tự thuật toán Kruskal, thuật toán Prim là trường hợp đặc biệt của thuật toán
cây khung nhỏ nhất tổng quát ở phần 23.1. Thuật toán Prim thực hiện giống thuật toán
Dijsktra trong việc tìm ra đường đi ngắn nhất trong đồ thị, ta sẽ tìm hiểu trong phần 24.3.
Tuy nhiên thuật toán Prim có đặc tính khác thuật toán Kruskal ở điểm một cạnh trong tập
A tạo một cây duy nhất. Như mô tả ở hình 23.5 cây bắt đầu từ một đỉnh gốc bất kỳ r và
xây dựng cây khung cho dến khi cây khung bao gồm tất cả các đỉnh ở trong V. Ở mỗi
bước của thuật toán, một cạnh nhẹ (light edge) được bổ sung vào cây A nối cây A với
một đỉnh duy nhất của G
A
=(V,A). Theo hệ quả 23.2, đây là quy tắc chỉ bổ sung các cạnh
an toàn cho A. Vì thế, khi thuật toán kết thúc, những cạnh trong A hình thành một cây
khung nhỏ nhất. Đây là phương pháp tham lam bởi vì ở mỗi bước của thuật toán ứng với
một cạnh có thể làm tăng trọng số nhỏ nhất vào trọng số của cây.
Vấn đề then chốt để thực hiện thuật toán Prim một cách hiệu quả là làm cho thuật

toán trở nên dễ dàng hơn bằng cách lựa chọn một cạnh mới để bổ sung vào cây và cây
được hình thành từ các cạnh trong tập A. Trong phần dưới đây, đồ thị liên thông G và
đỉnh gốc r của cây khung nhỏ nhất là đầu vào của thuật toán. Trong suốt quá trình thực
hiện thuật toán, tất cả các đỉnh không ở trên cây nằm thường trú trong hằng đợi Q theo
thứ tự ưu tiên nhỏ nhất dựa trên trường key. Ứng với mỗi đỉnh v, key[v] là trọng số nhỏ
nhất của một cạnh bất kỳ nối v với một đỉnh trong cây, và ta quy ước key[v]=∞ nếu
không có cạnh nào nối v với một đỉnh trong cây. Trường π[v] gọi là nút cha của đỉnh v
trong cây. Trong suốt quá trình thực hiện thuật toán, tập A trong GENERIC-MST được
xác định như sau:
A={(v,π[v]):v ∈ V - {r} - Q}
Khi thuật toán kết thúc hằng đợi Q theo thứ tự ưu tiên nhỏ nhất là rỗng. Cây khung nhỏ
nhất A của đồ thị G là:
A={(v,π[v]):v ∈ V - {r}}
MST-PRIM (G, w,r)
1. For each u ϵ V[G]
2. Do key[u] ∞
3. π[u]  NIL
4. key[r] 0
5. QV[G]
6. while Q ≠ ∅
7. do u EXTRACT-MIN(Q)
Trang 11
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
8. for each v∈ Adj[u]
9. do if v∈ Q and w(u,v) > key [v]
10. then π [v] u
11. key[v]  w(u,v)
Trang 12
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Hình 23.5 Thực hiện thuật toán Prim đối với đồ thị hình 23.1. Đỉnh gốc là đỉnh a.

Các cạnh được tô bóng thuộc vào cây đang phát triến và các đỉnh của cây được tô màu
đen. Ở mỗi bước của thuật toán, các đỉnh của cây xác định một phép cắt của đồ thị và
một cạnh nhẹ xuyên qua phép cắt được bổ sung vào cây. Ví dụ, ở bước thứ hai, thuật
toán lựa chọn bổ sung vào cây cạnh (b,c) hoặc cạnh (a,h) bởi vì hai cạnh này đều là các
cạnh nhẹ xuyên qua phép cắt.
Thuật toán Prim thực hiện như mô tả ở hình 23.5. Dòng 1-5 thiết lập key cho mỗi
đỉnh là ∞( ngoại trừ đỉnh gốc r thì giá trị ban đầu của nó là 0 vì vậy đỉnh r được xem như
là đỉnh xuất phát được xử lý),ban đầu gán đỉnh cha của mối đỉnh là Nil và hằng đợi Q
theo thứ tự ưu tiên nhỏ nhất chứa tất cả các đỉnh. Thuật toán phải duy trì tính bất biến
của ba phần như sau:
Trước khi đi vào vòng lặp While từ dòng 6-11:
1. A={(v,π[v]):v ∈ V - {r} - Q}
2. Các đỉnh sau khi xác định là các đỉnh của cây khung nhỏ nhất là những đỉnh nằm trong
tập V-Q
3. Mọi đỉnh v ∈ Q nếu π[v] ≠ NIL, key[v]<∞ và key[v] là trọng số của một cạnh (v,π[v])
nối v với một đỉnh của cây khung nhỏ nhất.
Dòng 7 xác định một đỉnh u thuộc Q gắn liền với một cạnh nhẹ xuyên qua phép cắt (V-
Q,Q)(ngoại trừ vòng lặp đầu tiên khi u=r ở dòng 4). Loại bỏ u khỏi tập Q và bổ sung u
vảo tập V-Q của các đỉnh trong câu vì vậy bổ sung (u,π(u)) vào A. Vòng lặp For ở dòng
8-11 cập nhật trường key và π của mỗi đỉnh v kề với đỉnh u nhưng không ở trong cây.
Việc cập nhật duy trì tính bất biến phần thứ 3 của vòng lặp.
Thuật toán Prim hoạt động dựa vào cách thức thực hiện hằng đợi Q theo thứ tự ưu
tiên nhỏ nhất. Nếu Q hoạt động như một binary min-heap (xem ở chương 6) thì ta có thể
sử dụng thủ tục BUILD-MIN-HEAP để thay thế cho các dòng lệnh từ dòng 1-5 thực hiện
mất O(V) thời gian. Vòng lặp while thực hiện|V|

lần và mỗi thao tác EXTRACT-MIN
thì thời gian thực hiệnlà O(lgV), vì vậy tổng thời gian thực hiện cho các lần gọi đến
EXTRACT-MIN là O(VlgV). Vòng lặp For ở dòng 8-11 thực hiện O(E) lần vì vậy tổng
chiều dài của tất cả các danh sách liền kề là 2|E|. Trong vòng lặp For, việc kiểm tra mỗi

đỉnh v thuộc Q ở dòng 9 có thể được thực hiện đồng thời bằng cách xem mỗi đỉnh là một
bit và giá trị của mỗi bit cho ta biết đỉnh v có thuộc Q hay không. Lệnh gán ở dòng 11
liên quan đến thao tác DECREASE-KEY trong min-heap và thao tác này có thể được
thực hiện trong một binary min-heap mất O(lgV). Vì vậy tổng thời gian thực hiện thuật
toán Prim là O(VlgV+ElgV)=O(ElgV) xem như gần bằng thời gian thực hiện thuật toán
Kruskal.
Trang 13
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Thời gian thực hiện thuật toán Prim có thể được cải tiến bằng cách sử dụng Fibonacci
heaps. Ở chương 20 ta nhận thấy rằng nếu có |V| phần tử trong một Fibonacci heap, thì ta
có thể thực thiện thao tác EXTRACT-MIN mất O(lgV) và thao tác DECREASE-KEY chỉ
mất thời gian thực hiện là O(1). Vì vậy, ta có thể sử dụng Fibonacci heap để thực hiện độ
ưu tiên của hằng đợi Q, do đó thời gian thực hiện thuật toán Prim sẽ được cải tiến thành
O(E+VlgV).
23-2-1 Bài tập
Giải thuật Kruskal có thể trả về nhiều cây khung khác nhau cho cùng đồ thị đầu vào G
phụ thuộc vào việc mối liên kết giữa các cạnh bị phá vỡ như thế nào khi các cạnh được
sắp xếp theo thứ tự. Chứng minh rằng mỗi cây khung nhỏ nhất T của G, trong đó có một
cách để sắp thứ tự các cạnh của G trong giải thuật Kruskal sao cho giải thuật trả về T.
23-2-2
Giả sử rằng đồ thị G = (V,E) được biểu diễn bằng một ma trận liền kề (adjacency).
Cho một cách thực hiện đơn giản của giải thuật Prim trong trường hợp mà nó chỉ thực
hiện mất O(V
2
)
23-2-3
Việc thực hiện theo Fibonaci heap của giải thuật Prim có tiệm cận nhanh hơn việc
thực hiện theo nhị phân vun đống cho đồ thị không đầy đủ G = (V, E) trong đó |E| =
Θ
(V

2
)? Và với trường hợp đồ thị đầy đủ mà trong đó |E| =
Θ
(V
2
)? |E| và |V| phải có mối
lien hệ như thế nào để thực hiện Fibonaci heap có thể tiệm cận nhanh hơn với cách thực
hiện theo binary-heap.
23-2-4
Giả sử rằng mọi trọng số cạnh trong một đồ thị là số nguyên trong phạm vi từ 1 tới |
V|. Làm thế nào để thực hiện nhanh thuật toán Kruskal? Điều gì sẽ xảy ra nếu trọng số
cạnh là các số nguyên trong phạm vi từ tới W với W là một hằng số nào đó.
23-2-5
Giả sử mọi trọng số cạnh trong một đồ thị là số nguyên trong phạm vi từ 1 tới |V|.
Làm thế nào để thực hiện nhanh thuật toán Prim? Điều gì sẽ xảy ra nếu trọng số cạnh là
các số nguyên trong phạm vi từ tới W với W là một hằng số nào đó.
23-2-6
Giả sử các trọng số cạnh trong đồ thị là được phân bố không trùng lặp trên một
khoảng mở [0,1). Giải thuật Prim hay Kruskal mà bạn có thể làm nó chạy nhanh hơn.
23-2-7
Trang 14
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
Giả sử một đồ thị G có một cây khung nhỏ nhất đã được tính toán. Làm thế nào để
cây khung nhỏ nhất có thể cập nhật một cách nhanh chóng khi một đỉnh và một cạnh
được bổ sung vào đồ thị G?
23-2-8
Giả sử giáo sư Toole đề xuất một giải thuật chia để trị mới để tính toán cho các cây
khung nhỏ nhất, như sau: Cho một đồ thị G = (V,E), chia tập đỉnh V thành 2 tập con V
1
và V

2
sao cho |V
1
| và |V
2
| khác 1. Đặt E
1
là tập các cạnh mà nó liền kề chỉ với các đỉnh
trong V
1
, và E
2
là tập các cạnh liền kề với các đỉnh của V
2
. Giải đệ qui cho bài toán cây
khung nhỏ nhất cho 2 đồ thị con G
1
= (V
1
, E
1
) và G
2
= (V
2
, E
2
). Cuối cùng, chọn một cạnh
trọng số nhỏ nhất trong E mà nó đi qua phần cắt (V
1

, V
2
), và sử dụng cạnh này để hợp
nên kết quả của 2 cây khung nhỏ nhất thành một cây khung nhỏ nhất.
Bạn có đồng ý rằng giải thuật này là đúng đắn theo nghĩa nó tính được một cây khung
nhỏ nhất, nếu không, hãy cho một ví dụ để chứng minh rằng giải thuật này sai.
23-2 Cây khung trong đồ thị không đầy đủ
Trong đồ thị không đầy đủ liên thông G= (V,E), ta có thể cải tiến thời gian thực hiện
thuật toán Prim O(E + V lgV) ở trên với công thức vun đống Fibonacci bằng cách thực
hiện tiền xử lý nhằm làm giảm số đỉnh đồ thị trước thi thực hiện thuật toán Prim. Cụ thể
hơn, với mỗi đỉnh u, ta chọn cạnh (u,v) kề u có trọng số nhỏ nhất, (u,v) chính là một cạnh
để xây dựng cây khung nhỏ nhất. Sau đó ta sẽ nối tất cả các cạnh (u,v) đã được chọn. Mỗi
lần kết nối một cạnh, ta sẽ tìm ra được một tập các đỉnh kết nối với cùng một cạnh mới
được chọn. Một đồ thị mới sẽ được hình thành sau mồi lần thực hiện việc kết nối các
cạnh nhờ vào việc “đổi tên” cạnh trong tập đỉnh chứa đỉnh cuối của nó. Một vài cạnh ở
đồ thị gốc ban đầu có thể được đặt tên lại. Trong trường hợp này, chỉ có một cạnh kết quả
và trọng số của nó chính là trọng số nhỏ nhất trong tập cạnh ban đầu.
Ban đầu, ta khởi tạo cây khung nhỏ nhất T là rỗng. Với mỗi cạnh (u,v) thuộc E, ta cho
orig[u,v] = (u,v) và c[u,v] = w[u,v]. Thuộc tính orig cho biết cạnh từ đồ thị khởi tạo ban
đầu có sự kết nối với một cạnh trong đồ thị rút gọn. Thuộc tính c cho biết trọng số của
cạnh, và mỗi khi có cạnh được nối kết giá trị này sẽ được cập nhật dựa vào sơ đồ lựa
chọn trọng số của cạnh. Thủ tục MST-Reduce có các giá trị input là G, orig, c, và T, giá
trị trả về là đồ thị G’ cùng với các giá trị orig’ và c’ đã được cập nhật tương ứng với G’.
Thủ tục này đồng thời cũng xác định các cạnh của G để tạo thành cây khung nhỏ nhất T.
MST-Recude( G, orig, c,T)
For each v∈V[G]
Do mark[v]  false
MAKE-Set(v)
Trang 15
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6

For each u∈V[G]
Do if mark[u] = FALSE
Then chooose v∈Adj[u] such that c[u,v] is minimized
UNION(u,v)
T T ∪ {orig[u,v]}
Mark[u]  mark[v]  TRUE
V[G’] {FIND-SET(v):v∈V[G]}
E[G’]  ∅
For each (x,y) ∈ E[G]
Do u  FIND-SET(x)
v  FIND-SET(y)
if (u,v) ∉ E[G’]
then E[G’]  E[G’] ∪ {(u,v)}
orig’[u,v]  orig[x,y]
c’[u,v]  c[x,y]
else if c[x,y] < c’[u,v]
then orig’[u,v]  orig[x,y]
c’[u,v]  c[x,y]
construct adjacency list Adj for G’
return G’, orig’, c’, and T
a. Gọi T là tập các cạnh trả về bởi thủ tục MST-Recude, A là cây khung nhỏ nhất có
được từ đồ thị G tạo bởi thủ tục MST-Prim(G’,c’,r) với r là một đỉnh bất kỳ thuộc
V[G’]. Chứng minh rằng T ∪ {orig’[x,y] : (x,y) ∈ A} là cây khung nhỏ nhất của
G.
b. Chứng tỏ IV[G’]I ≤ IVI/2
c. Chỉ ra cách thực hiện thủ tục MST-Reduce với thời gian thực hiện là O(E) hướng
dẫn: sử dụng cấu trúc dữ liệu đơn giản)
d. Giả sử thủ tục MST-Reduce được thực hiện k lần, sử dụng các giá trị đầu ra là G’,
orig’ và c’ có được từ một lần thực thi trước như là đầu vào G, orig và c cho lần
thực hiện tiếp theo và vun đống các cạnh trong T. Chứng tỏ rằng thời gian thực

hiện k lần MST- Reduce là O(kE).
e. Giả sử sau k lần thực hiện MST-Reduce ở câu d, ta thực thi thuật toán Prim bằng
lời gọi hàm MST-Prim(G’,c’,r), với G’ và c’ có được từ lần thực hiện cuối cùng
MST-Reduce và r là một đỉnh bất kỳ trong V[G’]. Hãy xác định giá trị k sao cho
Trang 16
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
tổng thời gian thực hiện là O(Elg lgV). Chứng tỏ với giá trị k đã chọn, tổng thời
gian thực hiện dần tiến tới giá trị nhỏ nhất.
f. Với giá trị nào của IEI (giới hạn bởi IVI) thì thuật toán Prim đã được tiền xử lý sẽ
tối ưu hơn thuận toán Prim không được tiền xử lý?
23-3 Cây cổ chai
Một cây cổ chai của đồ thị vô hướng G là một cây khung của G có trọng số lớn nhất
của cạnh là nhỏ nhất trong G. Ta nói rằng giá trị của cây khung cổ chai là trọng số của
cạnh có trọng số lớn nhất trong T.
a. Một cây khung nhỏ nhất là một cây khung cổ chai
Phát biểu a chỉ ra rằng để tìm một cây khung cổ chai ta tìm cây khung nhỏ nhất.
Tiếp theo, ta sẽ chỉ thời gian tìm kiếm là tuyến tính.
b. Tìm thuật toán với thời gian thực hiện tuyến tính cho kết quả là đồ thị G và một số
nguyên b, chứng tỏ giá trị của cây khung cổ chai là b
c. Sử dụng thuật toán ở câu b như là một thủ tục con trong thuật toán với thời gian
thực hiện tuyến tính cho bài toán cây khung cổ chai
23-4 Lựa chọn thuật toán cho cây khung nhỏ nhất
Trong vấn đề này, chúng tôi đưa ra ba thuật toán khác nhau. Các thuật toán có giá trị
vào là đồ thị cần xét và cho ra kết quả là tập cạnh T. Với mỗi thuật toán,ta phải chứng
minh T là cây khung nhỏ nhất hay T không phải là cây khung nhỏ nhất.
a. MAYBE-MST-A(G,w)
1. Sắp xếp các cạnh theo thứ tự giảm dần của trọng số
2. T  E
3. Với mỗi cạnh e lấy từ danh sách trên
4. Kiểm tra nếu T - {e} là một đồ thị liên thông

5. Thì T  T - {e}
6. Return T
b. MAYBE-MST-B(G,w)
1. T ∅
2. Với mỗi cạnh e lấy tùy ý
3. Thực hiện kiểm tra nếu T ∪ {e} không có chu trình
4. Thì T T∪{e}
5. Return T
c. MAYBE-MST-C(G,w)
Trang 17
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
1. T ∅
2. Với mỗi cạnh e lấy tùy ý
3. Thực hiện T T∪{e}
4. Kiểm tra nếu T có chu trình c
5. Thì e’ là cạnh có trọng số lớn nhất trong c
6. T T-{e}
7. Return T
Trang 18
Cây khung nhỏ nhất- Nhóm thực hiện: Nhóm 6
MỤC LỤC
Cây khung nhỏ nhất 1
23.1 Phát triển cây khung nhỏ nhất 2
Bài tập 6
23.2 Thuật toán Kruskal và Prim 8
23-2-1 Bài tập 14
23-2 Cây khung trong đồ thị không đầy đủ 15
23-3 Cây cổ chai 17
Trang 19

×