4
Tìm đường đi ngắn nhất với định tuyến Dijkstra Bài viết này xin giới thiệu với các bạn mới làm quen với tin học và thuật giải một thuật toán đơn giản nhưng lại có hiệu quả rất lớn trong việc tìm đường đi ngắn nhất trong đồ thị. Đó là thuật toán Dijkstra. Đây là thuật toán đã đăng tải trên tạp chí tin học & nhà trường từ những số đầu tiên nhưng bài viết này sẽ đăng tải đầy đủ về bài toán, phương thức đưa ra thuật giải cũng như đoạn chương trình đầy đủ. Rất thích hợp với những bạn mới làm quen với những thuật toán kinh điển. Dijkstra là 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) là 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 và tập các cạnh E (đồ thị có hướng hoặc vô 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 là giá trị của cạnh. Cho trước một đỉnh xác định v, gọi là đỉ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 có 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 mà khoảng cách ngắn nhất từ nó đế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 mà khoảng cách từ nó đến v là ngắn nhất. Với giả thiết rằng mỗi cung có 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 hóa giải thuật, giả sử G có n đỉnh và 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 có 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 và đỉnh nguồn là đỉnh 1. Dưới đây là giải thuật Dijkstra để giải bài toán trên : <!--[if !supportLineBreakNewLine]--> <!--[endif]--> procedure Dijkstra; begin

Thuat Toan Dijkstra Tim Duong Di Ngan Nhat Trong Do Thi

  • Upload
    ga-mo

  • View
    6

  • Download
    1

Embed Size (px)

DESCRIPTION

Thuat Toan Dijkstra Tim Duong Di Ngan Nhat Trong Do Thi

Citation preview

Tm ng i ngn nht vi nh tuyn Dijkstra

Tm ng i ngn nht vi nh tuyn DijkstraBi vit ny xin gii thiu vi cc bn mi lm quen vi tin hc v thut gii mt thut ton n gin nhng li c hiu qu rt ln trong vic tm ng i ngn nht trong th. l thut ton Dijkstra. y l thut ton ng ti trn tp ch tin hc & nh trng t nhng s u tin nhng bi vit ny s ng ti y v bi ton, phng thc a ra thut gii cng nh on chng trnh y . Rt thch hp vi nhng bn mi lm quen vi nhng thut ton kinh in.

Dijkstra l thut ton nh tuyn n gin tm ng i ngn nht gia 2 im bt k. Khng mt tnh tng qut, ta coi mi im (nt mng) l mt nh ca mt th, ta s dng thut ton Dijkstra gii quyt bi ton tm ng i ngn nht gia 2 im nh sau:

Bi ton: Cho th G vi tp nh V v tp cc cnh E ( th c hng hoc v hng). Mi cnh ca th c gn mt nhn (gi tr khng m), nhn ny cn c gi l gi tr ca cnh. Cho trc mt nh xc nh v, gi l nh ngun. Tm ng i ngn nht t nh v n cc nh cn li ca G. (Tc l tm ng i t v n cc nh cn li vi tng cc gi ca cc cnh trn ng i l nh nht). Nu nh th c hng th ng i ny l ng i c hng.

Thut ton Dijkstra: Ta c th gii bi ton bng cch xc nh mt tp hp S cha cc nh m khong cch ngn nht t n n nh ngun v bit. Khi u S = { V }. Sau ti mi bc ta s thm vo S cc nh m khong cch t n n v l ngn nht. Vi gi thit rng mi cung c mt gi tr khng m th ta lun lun tm c mt ng i ngn nht nh vy m ch i qua cc nh tn ti trong S. d dng chi tit ha gii thut, gi s G c n nh v nhn trn mi cung c lu trong mng C, tc l C[i, j] bng gi tr(c th xem l di) ca cung (i, j). Nu i v j khng c cung ni th ta cho C[i, j] =. Ta s dng mt mng D c n phn t lu di ca ng i ngn nht t v n mi nh ca th. Khi u th gi tr ny chnh l di cnh (v, i), tc D[i] = C[v, i]. Ti mi bc ca gii thut th D[i] s lu di ng i ngn nht t nh v n nh i, ng i ny ch i qua cc nh c trong S. ci t gii thut d dng, ta gi s cc nh ca th c nh s t 1 n n v nh ngun l nh 1. Di y l gii thut Dijkstra gii bi ton trn :

procedure Dijkstra; begin S := [1] ; { S ch cha nh ngun } for i:=2 to n do D[i] := C[1, i] ; { Khi u cc gi tr cho D } for i:=1 to n - 1 do begin Ly nh w trong V - S sao cho D[w] l nh nht ; Thm w vo S ; for mi nh u thuc V - S doD[u] := Min (D[u], D[w] + C[w, u]) ; end; end;

Nu mun lu tr li cc nh trn ng i ngn nht c th xy dng li ng i ny t nh ngun n cc nh khc, ta dng mt mng P. Mng ny s lu P[u] = w vi nh u l nh trc ca nh w trn ng i ngn nht. Lc khi u ta cho P[u] = 1, vi mi u khc 1. Gii thut Dijkstra trn s c vit li nh sau :

procedure Dijkstra ; begin S := [1] ; { S ch cha nh ngun } for i:=2 to n do begin D[i] := C[1, i] ; { Khi u cc gi tr cho D } P[i] := 1 ; { Khi u cc gi tr cho P } end ; for i:=1 to n - 1 do begin Ly nh w trong V - S sao cho D[w] l nh nht ; Thm w vo S ; for mi nh u thuc V - S doif (D[w] + C[w, u] < D [u]) thenbegin D[u] := D[w] + C[w, u] ; P[u] := w ; end ; end; end;

V d : p dng gii thut Dijkstra cho th hnh sau:

INCLUDEPICTURE "http://i243.photobucket.com/albums/ff221/vnschool/cacthuattoanhay/timduongdingan1.png" \* MERGEFORMATINET

procedure DijksTra;

begint:=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 kdobegin{Tim min}

min:=i;

for i:=1 to n doif (d[i]d[u]+c[u,i] thenif not((d[i]=i)and(d[u]=i)and(c[u,i]=i)) thenbegind[i]:=d[u]+c[u,i];

truoc[i]:=u

endend;

if d[v0]=i thenKhongCoDuongDielseQuayLaiMangTruocDeTimDuong

end;