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

Lý thuyết đồ thị - Tìm đường đi ngắn nhất với Dijkstra

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 (149.83 KB, 4 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

Lý thuy t đ thế ồ ị


<b>Tìm đ</b>

<b>ườ</b>

<b>ng đi ng n nh t – Dijkstra</b>

<b>ắ</b>

<b>ấ</b>


<b>Nh c l i</b>

<b>ắ ạ</b>



Thu t toán Dijkstra ch áp d ng đậ ỉ ụ ược cho đ th khơng có c nh âm. Thu t tốn s b t đ uồ ị ạ ậ ẽ ắ ầ


t đ nh xu t phát x và k t thúc khi đ nh y đã đừ ỉ ấ ế ỉ ược xét (t i u). ố ư <i>(Nh v y, v nguyên t cư ậ</i> <i>ề</i> <i>ắ</i>


<i>n u cũng có th tìm đế</i> <i>ể</i> <i>ường đi ng n nh t t đ nh x đ n t t c các đ nh trong đ th )ắ</i> <i>ấ ừ ỉ</i> <i>ế ấ ả</i> <i>ỉ</i> <i>ồ ị</i> .


M ng arrnCost s l u chi phí t i u (hi n t i) t đ nh xu t phát đ n các đ nh trong đ th .ả ẽ ư ố ư ệ ạ ừ ỉ ấ ế ỉ ồ ị


M t đ nh i đã độ ỉ ược xét xong (<i>finalized) s có arrnCost[i] chính là chi phí t i u.</i>ẽ ố ư


N u mu n in ra đế ố ường đi ng n nh t, ta s ph i s d ng thêm m t m ng ph đ l u l iắ ấ ẽ ả ử ụ ộ ả ụ ể ư ạ


đ nh trỉ ước đó (đ nh cha). Đỉ ường đi s đẽ ược duy t t đ nh y, đ n arrnPrevious[y], … đ nệ ừ ỉ ế ế


khi nào g p đ nh x thì d ng.ặ ỉ ừ


<b>Tóm t t thu t tốn</b>

<b>ắ</b>

<b>ậ</b>



Có th hi u ng n g n r ng t p đã xét xong (V\T) s để ể ắ ọ ằ ậ ẽ ược m r ng d n, b t đ u là đ nh x,ở ộ ầ ắ ầ ỉ


sau đó là đ nh xỉ 1 có chi phí đi t x đ n xừ ế 1 là bé nh t, r i đ n đ nh xấ ồ ế ỉ 2 có chi phí tích lũy đi từ


x ho c xặ 1 là bé nh t, r i đ n đ nh xấ ồ ế ỉ 3… c nh v y cho đ n khi đ nh y cũng thu c v t pứ ư ậ ế ỉ ộ ề ậ


đã xét xong (y ∈V\T hay y ∉ T).



Cũng gi ng nh thu t tốn tìm cây khung Prime, vi c tìm l i m t đố ư ậ ệ ạ ộ ường ng n nh t t t pắ ấ ừ ậ


đã xét xong V\T đ n t p ch a xét xong T s t n r t nhi u chi phí (c n 2 vịng for), do đó taế ậ ư ẽ ố ấ ề ầ


có th c i ti n b ng cách l u l i đ dài nh nh t đ n đ nh v ể ả ế ằ ư ạ ộ ỏ ấ ế ỉ ∈ T và ch c n 1 vòng for đỉ ầ ể


tìm đ nh có đ dài min. Dỉ ộ ưới đây là thu t toán Dijkstra:ậ


1. Kh i t o:ở ạ


o Thu t toán đậ ược b t đ u v i gi thi t là chi phí t đ nh xu t phát đ n t tắ ầ ớ ả ế ừ ỉ ấ ế ấ


c các đ nh khác là ∞ (có th s d ng tr đ c bi t là -1), tr chính đ nh xu tả ỉ ể ử ụ ị ặ ệ ừ ỉ ấ


phát x, có chi phí là 0 (dùng m ng ả <i>int arrnCost[MAX]):</i>
<i>arrnCost[i] = ∞, </i>∀<i>i ≠ x; arrnCost[k] = 0</i>


o Ngoài ra, ban đ u, t t c các đ nh đ u thu c v t p ch a xét xong (ầ ấ ả ỉ ề ộ ề ậ ư <i>not </i>
<i>finalized yet) T (dùng m ng </i>ả <i>int T[MAX]):</i>


<i>T[i] = true (1), </i>∀<i>i</i>


o Đ có th l u l i để ể ư ạ ường đi ng n nh t, ta c n s d ng thêm m t m ng (ắ ấ ầ ử ụ ộ ả <i>int </i>
<i>arrnPrevious[MAX])</i>


2. N u đ nh y ế ỉ ∉ T, nghĩa là y đã xét xong (finalized), và arrnCost[y] chính là chi phí t iố


u, ta d ng thu t tốn, in ra chi phí và đ ng đi ng n nh t.


ư ừ ậ ườ ắ ấ



3. Ch n m t đ nh v ọ ộ ỉ ∈ T (ch a xét xong) có chi phí nh nh t (dùng m t vịng for).ư ỏ ấ ộ


N u khơng tìm đế ược m t v nh v y, nghĩa là không th tìm độ ư ậ ể ược đường đi t xừ


đ n y (không liên thông). ế <b>D ng thu t tốnừ</b> <b>ậ</b> và thơng báo khơng tìm được đường đi.
4. Đánh d u v đã đấ ược xét xong (<i>finalized):</i> T := T\{v}


<i>T[v] = false (0))</i>


5. ∀k ∈ T, n u có c nh n i t v đ n k và chi phí t i u h nế ạ ố ừ ế ố ư ơ


<i>arrnCost[k] == -1 (ch a xét)ư</i>


<i>ho c arrnCost[k] > arrnCost[v] + a[v, k]ặ</i> <i>(t i u h n)ố ư</i> <i>ơ</i>


</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

Lý thuy t đ thế ồ ị


thì ta s c p nh t l i chi phí t i uẽ ậ ậ ạ ố ư


<i>ho c arrnCost[k] > arrnCost[v] + a[v, k]ặ</i>


6. Quay l i bạ ước 2


Dưới đây là minh h a cho thu t toán Dijkstra v i đ nh xu t phát là 1, đ nh k t thúc là 2.ọ ậ ớ ỉ ấ ỉ ế


ch n v = 1ọ


c p nh t giá tr cho đ nh 1 và đ nh 3ậ ậ ị ỉ ỉ



Lê Th y Anhụ 2/4


2
1
2
4
5
2
0
1
3
<b>cost = 0</b>


cost = ∞


cost = ∞


cost = ∞


2
1
2
4
5
2
0
1
3
<b>cost = 0</b>



previous = 1
cost = 2


cost = ∞


cost = 5,
previous = 1


2
1
2
4
5
2
0
1
3


cost = 0


previous = 1


<b>cost = 2</b>


cost = ∞


cost = 5,
previous = 1


2


1
2
4
5
2
0
1
3


cost = 0


previous = 1


<b>cost = 2</b>


previous = 0
cost = 6


cost = 3
previous = 0
C p nh tậ ậ


2
1
2
4
5
2
0
1


3


cost = 0


previous = 1
cost = 2


previous = 0
cost = 6


<b>cost = 3</b>


previous = 0


2
1
2
4
5
2
0
1
3


cost = 0


previous = 1
cost = 2


previous = 3


cost = 5


<b>cost = 3</b>


previous = 0


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

Lý thuy t đ thế ồ ị


Nh n xét r ng, thu t toán trên ch đúng khi, chi phí đ n các đ nh xậ ằ ậ ỉ ế ỉ i ln ≤ chi phí các đ nhỉ


xj (vói j≤i). N u nh trong đ th có c nh âm, đế ư ồ ị ạ ường đi tìm được có th s không là t i u.ể ẽ ố ư


Xét ví d dụ ưới hình sau v i đ nh xu t phát là 0, đ nh k t thúc là 2:ớ ỉ ấ ỉ ế


B1: T = {0, 1, 2}, arrnCost[] = {0, ∞, ∞},
B2: v = 0 ⇒ T = {1, 2}, arrnCost[] = {<b>0</b>, 3, 2}
B3: v = 2 ⇒ T = {1}, arrnCost[] = {0, 3, <b>2</b>}


B4: 2 ∉ T, d ng thu t tốn. Chi phí ng n nh t tìm đừ ậ ắ ấ ược là
2.


Rõ ràng là n u ta đi theo 0 → 1 → 2 thì chi phí là 1 (3-2),ế


chi phí 2 tìm được khơng ph i là chi phí ng n nh t.ả ắ ấ


<b>Cài đ t – c u trúc d li u</b>

<b>ặ</b>

<b>ấ</b>

<b>ữ ệ</b>


Ta c n 3 m ng sauầ ả


int T[MAX];



int arrnCost[MAX]; // dùng double n u ma tr n k s d ng doubleế ậ ề ử ụ
int arrnPrevious[MAX];


<b>Cài đ t – Hàm kh i t o InitDijkstra</b>

<b>ặ</b>

<b>ở ạ</b>


void InitDijkstra()


{


<i>// c p nh t chi phí cho các đ nh là vô c c (-1),ậ</i> <i>ậ</i> <i>ỉ</i> <i>ự</i>
<i>// t p T g m t t c các đ nhậ</i> <i>ồ</i> <i>ấ</i> <i>ả</i> <i>ỉ</i>


for (i…)
{



}


<i>// riêng đ nh xu t phát có chi phí là 0ỉ</i> <i>ấ</i>
arrnCost[nStartNode] = 0;


}


<b>Cài đ t – Hàm Dijkstra</b>

<b>ặ</b>


void Dijkstra()


{


<i>// d ng n u nh y ừ</i> <i>ế</i> <i>ư</i> ∉<i> T</i>
while (…)



Lê Th y Anhụ 3/4


2


1
2
4


5


2
0


1


3


cost = 0


previous = 1
cost = 2


previous = 3


<b>cost = 5</b>


cost = 3
previous = 0


2



1
2
4


5


2
0


1


3


cost = 0


previous = 1
cost = 2


previous = 3


<b>cost = 5</b>


cost = 3
previous = 0


3


2



-2
1


0


</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

Lý thuy t đ thế ồ ị


{


v = -1;


<i>// tìm trong t p T, ch n đ nh có chi phí min nh tậ</i> <i>ọ</i> <i>ỉ</i> <i>ấ</i>
for (i…)


if (… && (… || …))


// ch n đ nh i là đ nh minọ ỉ ỉ


<i>// n u khơng có v nh th , d ng thu t tốn (khơng liên thơng)ế</i> <i>ư</i> <i>ế</i> <i>ừ</i> <i>ậ</i>
if (…)


break;


<i>// lo i b v kh i Tạ</i> <i>ỏ</i> <i>ỏ</i>


<i>// c p nh t đ dài các đ nh k ậ</i> <i>ậ</i> <i>ộ</i> <i>ỉ</i> ∈<i> T, n u có đế</i> <i>ường đi t v ừ</i> <i>→ k</i>
<i>// và (arrnCost[k] là ∞ ho c arrnCost[k] > arrnCost[v]+a[v][k]ặ</i>
for (k…)



if (… && … && (… || …))


}
}


<b>Hàm in đ</b>

<b>ườ</b>

<b>ng đi – PrintResult</b>



o N u nh y thu c T, nghĩa là y v n ch a đế ư ộ ẫ ư ược xét xong, ta khơng tìm được đường
đi t x đ n y.ừ ế


o N u nh y khơng thu c T, khi đó arrnCost[y] chính là chi phí t i u t x đ n y. ế ư ộ ố ư ừ ế


Khi đó dị theo y → y1=arrnParents[y] → y2=arrnParents[y1] → ... cho đ n khi ta g pế ặ


đ nh x.ỉ


void PrintResult()
{


if (T[i])


printf(“Khong co duong di…”);
else


{


printf(“Chi phi toi uu la…”);
printf(“Duong di tim duoc…”);


k = y;


printf(“%d”, k);
while (k != x)
{


k = arrnPrevious[k];
printf(“ <-- %d”, k);
}


}
}


</div>

<!--links-->

×