Toán học - Bài 9: Bài toán đường đi ngắn nhất trên đồ thị
Bạn đang xem 20 trang mẫu của tài liệu "Toán học - Bài 9: Bài toán đường đi ngắn nhất trên đồ thị", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- toan_hoc_bai_9_bai_toan_duong_di_ngan_nhat_tren_do_thi.pdf
Nội dung text: Toán học - Bài 9: Bài toán đường đi ngắn nhất trên đồ thị
- BÀI 9 BÀI TOÁN ĐƯỜNG ĐI NGẮN NHẤT TRÊN ĐỒ THỊ Giáo viên: TS. Nguyễn Văn Hiệu Email: nvhieuqt@dut.udn.vn 1
- Nội dung • Giới thiệu 0 • Bài toán 8 A 4 • Thuật toán Ford-Bellman 2 8 2 3 • Thuật toán Dijkstra 7 1 • Thuật toán Floyd B C D 3 9 5 8 2 5 E F Nguyễn Văn Hiệu, 2012, Discrete Mathematics 2
- Giới thiệu Có nhiều cách đi giữa hai điểm Chọn ngắn nhất theo d(u,v)=? nghĩa cự ly, Chọn đường đi nhanh nhất theo nghĩa thời gian G = (V , E) mi j =1 Chọn đường đi rẽ nhất theo chi phí, Chọn gửi dữ liệu nhanh mi j >0 nhất. Nguyễn Văn Hiệu, 2012, Discrete Mathematics 3
- Bài toán Cho G = (V, E) là đồ thị có trọng lượng. s ∈ V và t ∈ V. Hãy tìm đường đi có tổng trọng lượng nhỏ • Đường đi ngắn nhất từ Etna đến nhất từ s đến t. Oldtown là: Etna – Bangor – Orono – OldTown • Đường đi ngắn nhất từ Hermae đến Etna là: Hermae – Hampdea – Bangor - Etna Nguyễn Văn Hiệu, 2012, Discrete Mathematics 4
- Bài toán Điều kiện bài toán Phải tồn tại đường đi từ s Trong đồ thị không tồn tại đến t: chu trình âm Đồ thị vô hướng liên thông Đồ thị có hướng: không tồn Đồ thị có hướng liên thông tại chu trình âm. mạnh Đồ thị vô hướng: không tồn Đồ thị vô hướng, s và t nằm tại cạnh âm. trong cùng một thành phần liên thông Đồ thị có hướng, có tồn tại đường đi từ s đến t
- Bài toán Nhận xét Nếu v là đỉnh trung gian trên đường đi ngắn nhất từ s đến t thì đường đi từ s đến v phải là ngắn nhất và đường đi từ v đến t cũng phải là ngắn nhất. Do đó, để tối ưu, người ta mở rộng bài toán tìm đường đi ngắn nhất từ một đỉnh đến tất cả các đỉnh còn lại của đồ thị.
- Thuật toán Ford-Bellman Ý tưởng • Dò tìm bằng cách thử đi qua các đỉnh trung gian Nếu phát hiện đường đi qua đỉnh trung gian ngắn hơn đường đi hiện tại thì sẽ cập nhật đường đi mới, đồng thời chỉnh sửa các thông tin liên quan. • Sử dụng hai mảng – Mảng d[v]: Lưu trữ độ dài đường if d[v] > d[u] + c[u,v] then đi ngắn nhất hiện tại từ s đến v. { d[v] = d[u] + c[u,v]; – Mảng T[v]: Lưu trữ đỉnh nằm Truoc[v] = u; } trước v trên đường đi ngắn nhất hiện tại.
- Thuật toán Ford-Bellman • * Khởi tạo * for v V d[v]:= c[s,v]; T[v]:=s; • * Bắt đầu * d[s]:=0; for k:=1; k ≤ n-2 k 1 2 3 4 5 for v V\{ s} for u V 0,1 1,1 ,1 ,1 3,1 if d[v] > d[u] + c[u,v] 1 0,1 1,1 4,2 4,2 -1,3 d[v]:=d[u]+c[u,v]; T[v]:=u; 2 0,1 1,1 4,2 3,5 -1,3 3 0,1 1,1 4,2 3,5 -1,3
- Thuật toán Ford-Bellman k 1 2 3 4 5 6 0,1 1,1 ,1 ,1 ,1 ,1 1 0,1 1,1 6 ,2 3 ,2 7,4 7,3 2 0,1 1,1 4 ,4 3 ,2 7,4 5,3 3 0,1 1,1 4 ,4 3 ,2 6,6 5,3 S = 1 4 0,1 1,1 4 ,4 3 ,2 6,6 5,3
- Thuật toán Ford-Bellman Nhận xét: Cải tiến: • Áp dụng được cho mọi • Không thể cải tiến tốt trường hợp hơn cho trường hợp • Chi phí tính toán lớn do tổng quát dùng 3 vòng lặp lồng nhau • Chỉ có thể làm tốt hơn • Thường lãng phí một số bước sau cùng cho một số trường hợp riêng
- Thuật toán Dijkstra Nhận xét thuật toán Ford-Bellman k 1 2 3 4 5 6 0,1 1,1 ,1 ,1 ,1 ,1 1 0,1 1,1 6 ,2 3 ,2 7,4 7,3 2 0,1 1,1 4 ,4 3 ,2 7,4 5,3 3 0,1 1,1 4 ,4 3 ,2 6,6 5,3 S = 1 4 0,1 1,1 4 ,4 3 ,2 6,6 5,3 • Kết quả của bảng đã ổn định từ sớm • Trên một dòng, giá trị d nhỏ nhất không thay đổi về sau nếu trọng số các cạnh là không âm
- Thuật toán Dijkstra Chú ý Ý tưởng • Thuật toán này chỉ dùng cho • Do không có cạnh âm nên tại đồ thị không có cạnh âm. mỗi bước, sẽ có một đỉnh mà thông tin về nó sẽ không thay đổi về sau • Tại mỗi bước, ta không cần phải kiểm tra qua tất cả các đỉnh trung gian, mà chỉ: – Chọn một đỉnh u có giá trị d[u] nhỏ nhất – Chọn u làm đỉnh trung gian để xác định các bước kế tiếp
- Thuật toán Dijkstra (* Khởi tạo *) for v V d[v]:=c[s,v]; T[v]:=s; d[s]:=0; T: =V\{s}; (*T tập đỉnh chưa cố định *) (* Bước lặp *) k 1 2 3 4 5 6 while T d[u]+c[u,v] 4 ,4* d[v]:=d[u]+c[u,v]; 2 7,4 8,2 T[v]:=u; 3 7,4 5,3* 4 6,6*
- Thuật toán Dijkstra Ví dụ Demo Result Source Code
- Thuật toán Floyd Mục tiêu Giải pháp • G đồ thị có hướng hướng, • Sử dụng Dijkstra nhiều lần liên thông , có trọng số • Sử dụng thuật toán Floyd • Tìm đường đi ngắn nhất với mọi cặp đỉnh Nguyễn Văn Hiệu, 2012, Discrete Mathematics 15
- Thuật toán Floyd Input Output Ma trận trọng số C Ma trận đường đi ngăn nhất giữa các cặp đỉnh {d[i,j] } i,j =1 n, d[i,j] – độ dài đường đi từ i đến j Ma trận ghi nhận đường đi {p[i,j] }i,j =1 n, p[i,j] – ghi nhận đỉnh đi trước đỉnh j trong đường đi ngắn nhất từ i đến j Nguyễn Văn Hiệu, 2012, Discrete Mathematics 16
- Thuật toán Floyd // Khởi tạo 10 For i:=1 to n do 1 2 3 For j:=1 to n do{ 6 d[i,j] := a[i,j]; 2 5 p[i,j] := i; } 1 // Bước lặp 4 3 For k:=1 to n do 1111 For i:=1 to n do 10 6 2 2222 For j:=1 to n do 10 5 3 If(d[i,j]>d[i,k]+d[k,j]){ 6 5 1 3333 d[i,j] := d[i,k] + d[k,j]; 2 3 1 4444 p[i,j] := p[k,j]; } Ma trận d Ma trận p Nguyễn Văn Hiệu, 2012, Discrete Mathematics 17
- Thuật toán Floyd 10 6 2 1111 1 10 2 10 5 3 2222 3 tạo 6 5 1 3333 2 6 5 Khởi 2 3 1 4444 1 Ma trận d Ma trận p 4 3 10 6 2 10 5 3 k=3 k=1 6 5 1 2 3 1 5 3 2 1 4 4 1 5 4 3 4242 k=4 k=2 3 4 1 4433 2 3 1 4444 Nguyễn Văn Hiệu, 2012, Discrete Mathematics 18
- Thuật toán Floyd 10 1 2 5 3 2 1 4 4 1 3 5 4 3 4242 2 6 5 3 4 1 4433 1 3 4 2 3 1 4444 Đọc đường đi: Từ 1 đến 3: Trước 3 là p[1,3] = 4. Vậy 4 là đỉnh nằm trước 3 trên đường đi . Trước 4 là p[1,4] = 1. Vậy 1 là đỉnh nằm trước 4 trên đường đi . Dừng. Đường đi là: 1 – 4 – 3 với độ dài là d[1,3] = 3 Tương tự, đường đi ngắn nhất từ 3 đến 2 là: 3 – 4 – 2 với độ dài là d[3,2] = 4 Nguyễn Văn Hiệu, 2012, Discrete Mathematics 19
- Bài tập Lập trình thực hiện các thuật toán mô tả: Thuật toán Dijkstra Thuật toán Floyd Xác định độ phức tạp của 2 thuật toán trên Nguyễn Văn Hiệu, 2012, Discrete Mathematics 20
- THAT’S ALL; THANK YOU What NEXT?