Tìm đ ng đi ng n nh t v i đ nh tuy n Dijkstraườ ế
Bài viết này xin gii thiu vi các bn mi làm quen vi tin hc và thut gii mt thut toán đơn gin nhưng li
có hiu qu rt ln trong vic tìm đường đi ngn nht trong đồ th. Đó là thut toán Dijkstra. Đây là thut toán
đã đăng ti trên tp chí tin hc & nhà trường t nhng s đầu tiên nhưng bài viết này s đăng ti đầy đủ v bài
toán, phương thc đưa ra thut gii cũng như đon chương trình đầy đủ. Rt thích hp vi nhng bn mi làm
quen vi nhng thut toán kinh đin.
Dijkstra thu t toán đ nh tuy n đ n gi n đ tìm đ ng đi ng n nh t gi a 2 đi m b t kỳ. Không m t ế ơ ườ
tính t ng quát, ta coi m i đi m (nút m ng) m t đ nh c a m t đ th , ta s dùng thu t toán Dijkstra đ
gi i quy t bài toán tìm đ ng đi ng n nh t gi a 2 đi m nh sau: ế ườ ư
Bài toán: Cho đ th G v i t p đ nh V t p các c nh E th h ng ho c h ng). M i c nh ướ ướ
c a đ th đ c gán m t nhãn (giá tr không âm), nhãn này còn đ c g i giá tr c a c nh. Cho tr c ượ ượ ướ
m t đ nh xác đ nh v, g i đ nh ngu n. Tìm đ ng đi ng n nh t t đ nh v đ n các đ nh còn l i c a G. ườ ế
(T c là tìm đ ng đi t v đ n các đ nh còn l i v i t ng các giá c a các c nh trên đ ng đi là nh nh t). ườ ế ườ
N u nh đ th có h ng thì đ ng đi này là đ ng đi có h ng. ế ư ướ ườ ườ ướ
Thu t toán Dijkstra: Ta th gi i bài toán b ng cách xác đ nh m t t p h p S ch a các đ nh
kho ng cách ng n nh t t đ n đ nh ngu n v đã bi t. Kh i đ u S = { V }. Sau đó t i m i b c ta s ế ế ướ
thêm vào S các đ nh kho ng cách t đ n v ng n nh t. V i gi thi t r ng m i cung m t giá ế ế
tr không âm thì ta luôn luôn tìm đ c m t đ ng đi ng n nh t nh v y mà ch đi qua các đ nh đã t n t i ượ ườ ư
trong S. Ð d dàng chi ti t a gi i thu t, gi s G n đ nh nhãn trên m i cung đ c l u trong ế ượ ư
m ng C, t c là C[i, j] b ng giá tr (có th xem là đ dài) c a cung (i, j). N u i và j không có cung n i thì ta ế
cho C[i, j] =Ġ. Ta s dùng m t m ng D n ph n t đ l u đ dài c a đ ng đi ng n nh t t v đ n ư ườ ế
m i đ nh c a đ th . Kh i đ u thì giá tr này chính là đ dài c nh (v, i), t c D[i] = C[v, i]. T i m i b c ướ
c a gi i thu t thì D[i] s l u đ dài đ ng đi ng n nh t t đ nh v đ n đ nh i, đ ng đi này ch đi qua các ư ườ ế ườ
đ nh đã trong S.
Ð cài đ t gi i thu t d dàng, ta gi s các đ nh c a đ th đ c đánh s t 1 đ n n đ nh ngu n ượ ế
đ nh 1. D i đây gi i thu t ướ Dijkstra đ gi i bài toán trên :
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
procedure Dijkstra;
begin
S := [1] ; { S ch ch a đ nh ngu n }
for i:=2 to n do
D[i] := C[1, i] ; { Kh i đ u các giá tr cho D }
for i:=1 to n - 1 do
begin
L y đ nh w trong V - S sao cho D[w] là nh nh t ;
Thêm w vào S ;
for m i đ nh u thu c V - S do
D[u] := Min (D[u], D[w] + C[w, u]) ;
end;
end;
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
N u mu n l u tr l i các đ nh trên đ ng đi ng n nh t đ có th xây d ng l i đ ng đi này t đ nhế ư ườ ườ
ngu n đ n các đ nh khác, ta dùng m t m ng P. M ng này s l u P[u] = w v i đ nh u là đ nh tr c c a ế ư ướ
đ nh w trên đ ng đi ng n nh t. Lúc kh i đ u ta cho P[u] = 1, v i m i u khác 1. ườ
Gi i thu t Dijkstra trên s đ c vi t l i nh sau : ượ ế ư
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
procedure Dijkstra ;
begin
S := [1] ; { S ch ch a đ nh ngu n }
for i:=2 to n do
begin
D[i] := C[1, i] ; { Kh i đ u các giá tr cho D }
P[i] := 1 ; { Kh i đ u các giá tr cho P }
end ;
for i:=1 to n - 1 do
begin
L y đ nh w trong V - S sao cho D[w] là nh nh t ;
Thêm w vào S ;
for m i đ nh u thu c V - S do
if (D[w] + C[w, u] < D [u]) then
begin
D[u] := D[w] + C[w, u] ; P[u] := w ;
end ;
end;
end;
Ví d : Áp d ng gi i thu t Dijkstra cho đ th hình sau:
<!--[if !supportLineBreakNewLine]-->
procedure DijksTra;
begin
t:=false;
t[u0]:=true;
d[i]:=c[u0,i];{Neu khong co duong di thi d[i]=i’}
k:=1;{Da ket nap duoc 1 dinh}
while kdo
begin
{Tim min}
min:=i’;
for i:=1 to n do
if (d[i]<MIN)and(not t[i])then
begin
u:=i;
min:=d[u]
end;
t[u]:=true;{thêm u vao tp đnh}
inc(k);
{Tính li đường đi}
for i:=1 to n do
if d[i]>d[u]+c[u,i] then
if not((d[i]=i’)and(d[u]=i’)and(c[u,i]=i’)) then
begin
d[i]:=d[u]+c[u,i];
truoc[i]:=u
end
end;
if d[v0]=i’ then
KhongCoDuongDi
else
QuayLaiMangTruocDeTimDuong
end;