Các thu t toán tìm ki m trên đ th ế
Thut toán tìm kiếm theo chiu sâu
Tư tưởng chính ca thut toán là: Gi s chúng ta đang xét trên đồ th G(V,E). T mt đỉnh
u V hin thi nào đó ta s thăm ti đnh k v ca u và quá trình được lp li đối vi đỉnh v.
bước tng quát, gi s hin ti đang xét đỉnh u0, chúng ta s có hai kh năng s xy ra:
-Nếu như tn ti mt đỉnh v0 k vi u0 mà chưa đưc thăm thì đỉnh v0 đó s tr thành đỉnh đã
thăm và quá trình tìm kiếm li bt đu t đỉnh v0 đó.
-Ngược li, nếu mi đỉnh k vi u0 đều đã thăm thì ta s quay tr li đỉnh mà trước đó ta đến
đỉnh u0 để tiếp tc quá trình tìm kiếm.
Như vy, trong quá trình thăm đỉnh bng thut toán tìm kiếm theo chiu sâu, đỉnh được thăm
càng mun càng sm được duyt xong (Cơ chế Last In First Out - Vào sau ra trước). Do đó,
ta có th t chc quá trình này bng mt th tc đệ quy như sau:
Procedure DFS(u);
Begin
Visit(u);
Daxet[u]:=True;
For v K (u do
if not Daxet[v] then DFS(v);
End;
Và th tc duyt h thng toàn b đỉnh ca đồ th s là:
Procedure Find;
Begin
Fillchar(Daxet,SizeOf(Daxet),False);
For u V do
If not Daxet[u] then DFS(u);
End;
D nhn thy rng, mi ln gi DFS(u) thì toàn b các đỉnh cùng thành phn liên thông vi u
s được viếng thăm. Th tc Visit(u) là thao tác trên đỉnh u trong tng bài toán đặt ra c th.
Thut toán tìm kiếm theo chiu rng
Thut toán này thc ra là s ci biến v th t duyt đỉnh trên đồ th ca tìm kiếm theo chiu
sâu bng cách thay vì dùng mt STACK thì ta li dùng mt hàng đợi QUEUE để kết np đỉnh
được thăm. Như vy, đỉnh được thăm càng sm s càng sm tr thành duyt xong (cơ chế
First In First Out - Vào trước ra trước). Th tc được mô t dưới đây:
Procedure BFS(u);
Begin
Queue:=Empty
K t n p u vào Queue;ế
Daxet[u]:=True;
While Queue<>Empty do
Begin
L y v t Queue;
Visit(v);
For w K (v) do
If not Daxet[w] then
Begin
K t n p w vào Queue;ế
Daxet[w]:=True;
End;
End;
End;
Ta có th tc tìm kiếm theo chiu rng là:
Procedure Find;
Begin
Fillchar(Daxet,SizeOf(Daxet),False);
For u V do
If not Daxet[u] then BFS(u);
End;
Tương t như thut toán tìm kiếm theo chiu sâu, thut toán này mi ln gi th tc BFS(u)
thì mi đỉnh cùng thành phn liên thông vi u s được thăm. Th tc Visit(u) như đã nói
trên.
Để hiu rõ hơn v thut toán, các bn có th xem thêm bài viết "Thut toán Loang" ca
cùng tác gi s báo 2(7) năm 2000. Xin chân thành cm ơn.
T hai thut toán trên, rt nhiu bài toán cơ bn trên đồ th được gii quyết rt d dàng. Vì
khuôn kh bài báo, xin trình by mt s bài toán kinh đin. Mt s vn đề khác, s trình bày
mt bài báo khác.
1.Bài toán tìm thành phn liên thông ca đồ th
Cho mt đồ th G=(V.E). Hãy cho biết s thành phn liên thông ca đồ th và mi thành phn
liên thông gm nhng đỉnh nào.
Như ta đã biết, các th tc DFS(u) và BFS(u) cho phép viếng thăm tt c các đỉnh có cùng
thành phn liên thông vi u nên s thành phn liên thông ca đồ th chính là s ln gi th tc
trên. Ta s dùng thêm biến đếm Connect để đếm s thành phn liên thông.
Và vòng lp chính trong các th tc tìm kiếm theo chiu sâu hay chiu rng ch cn sa li
như sau:
Procedure Find;
Begin
Fillchar(Daxet,SizeOf(Daxet),False);
Connect:=0;
For u V do
If not Daxet[u] then
Begin
Inc(Connect); DFS(u); (*BFS(u)*)
End;
End;
Th tc Visit(u) s làm công vic đánh s thành phn liên thông ca đỉnh u:
LienThong[u]:=Connect;
2.Bài toán tìm đường đi gia hai đỉnh ca đồ th
Cho đồ th G=(V,E). Vi hai đỉnh s và t là hai đỉnh nào đó ca đồ th. Hãy tìm đường đi t s
đến t.
Do th tc DFS(s) và BFS(s) s thăm ln lượt các đỉnh liên thông vi u nên sau khi thc hin
xong th tc thì có hai kh năng:
-Nếu Daxet[t]=True thì có nghĩa: tn ti mt đưng đi t đỉnh s ti đỉnh t.
-Ngược li, thì không có đường đi ni gia s và t.
Vn đề còn li ca bài toán là: Nếu tn ti đường đi ni đỉnh s và đỉnh t thì làm cách nào để
viết được hành trình (gm th t các đỉnh) t s đến t.
V k thut ly đường đi này cũng đã được trình by trong bài viết "Thut toán Loang"!. Xin
nhc li c th là: Dùng mt mng Truoc vi: Truoc[v] là đỉnh trước ca v trong đường đi. Khi
đó, câu lnh If trong th tc DFS(u) được sa li như sau:
If not Daxet[v] then
Begin
DFS(v);
Truoc[v]:=u;
End;
Còn vi th tc BFS ta cũng sa li trong lnh If như sau:
If not Daxet[w] then
Begin
K t n p w vào Queue;ế
Daxet[w]:=True;
Truoc[w]:=v;
End;
Vic viết đường đi lên màn hình (hoc ra file) có th có 3 cách:
-Viết trc tiếp da trên mng Truoc: Hin nhiên đường đi hin th s ngược t đỉnh t tr v s
như sau:
-Dùng thêm mt mng ph P: cách này dùng để đảo đường đi t mng Truoc để có đưng đi
thun t đỉnh s đến đỉnh t.
-Cách th 3: là dùng chương trình đệ quy để viết đường đi.
Procedure Print_Way(i:Byte);
If i<>s then
Begin
Print_Way(Truoc[i]);
Write('đ',i);
End;
Li gi th tc đệ quy như sau:
Write(s);
Print_Way(s);