Thuật toán Dijkstra được sử dụng với mục đích tìm đường đi ngắn nhất giữa các đỉnh trong một đồ thị có hướng hoặc vô hướng với trọng số không âm.. Thuật toán này được sử dụng để tìm đườn
Trang 1TRƯỜNG ĐẠI HỌC KINH TẾ QUỐC DÂN VIỆN CÔNG NGHỆ THÔNG TIN & KINH TẾ SỐ
-o0o -BÀI TẬP NHÓM 5 MÔN HỌC: MẠNG MÁY TÍNH VÀ TRUYỀN SỐ LIỆU
ĐỀ TÀI: TÌM ĐƯỜNG ĐI NGẮN NHẤT THEO
GIẢI THUẬT DIJKSTRA
Trang 2MỞ ĐẦU
Mạng máy tính đóng vai trò quan trọng trong việc truyền tải thông tin và kết nối các thiết bị với nhau Để đảm bảo việc truyền tải thông tin một cách hiệu quả và tối ưu nhất, thuật toán Dijkstra đã trở thành một công cụ quan trọng trong lĩnh vực này Thuật toán Dijkstra được sử dụng với mục đích tìm đường đi ngắn nhất giữa các đỉnh trong một đồ thị có hướng hoặc vô hướng với trọng số không âm Với khả năng xác định đường đi tối
ưu, thuật toán Dijkstra đã được áp dụng rộng rãi trong thực tế như tìm đường đi ngắn nhất trên bản đồ, trong mạng xã hội hay trong hệ thống thông tin di động…
Trên cơ sở đó, bài luận này sẽ tập trung vào việc giới thiệu, phân tích và cài đặt Tìm đường đi ngắn nhất theo giải thuật Dijkstra
Trang 3MỤC LỤC
MỞ ĐẦU 1
MỤC LỤC 2
DANH MỤC HÌNH VẼ 3
NỘI DỤNG 4
Chương 1: Tổng quan về bài toán đường đi ngắn nhất 4
I Đồ thị có trọng số 4
1 Khái niệm: 4
2 Ưu nhược điểm của phương pháp biểu diễn đồ thị có trọng số 5
3 Ứng dụng 5
II Bài toán đường đi ngắn nhất 6
1 Phát biểu bài toán 6
2 Các ứng dụng thực tế 6
3 Các dạng bài toán đường đi ngắn nhất 7
Chương 2: Thuật toán DIJKSTRA 8
I Giới thiệu về thuật toán DIJKSTRA 8
1 Khái niệm 8
2 Đặc điểm 8
3 Yêu cầu cơ bản để thực hiện thuật toán 9
II Mô tả thuật toán 10
1 Ý tưởng thuật toán 10
2 Phương pháp thuật toán 12
3 Giả mã thuật toán 13
4 Lưu đồ thuật toán 14
5 Ví dụ và chứng minh thuật toán 14
III Đánh giá 22
1 Ưu điểm 22
2 Nhược điểm 22
IV Ứng dụng của thuật toán Dijkstra 22
1 Ứng dụng của thuật toán 22
2 Một ứng dụng cụ thể 23
Chương 3: Cài đặt và thử nghiệm 24
KẾT LUẬN 30
TÀI LIỆU THAM KHẢO 31
Trang 4DANH MỤC HÌNH VẼ
Hình 1: Đồ thị minh họa 4
Hình 2: Đồ thị minh họa 6
Hình 3: Minh họa về các bước triển khai của thuật toán Dijkstra tìm đường đi ngắn nhất 11
Hình 4: Đồ thị minh họa 12
Hình 5: Lưu đồ thuật toán Dijkstra 14
Hình 6: Đồ thị minh họa 15
Hình 7: Gắn cho A nhãn 0, các nhãn khác có nhãn là +oo 15
Hình 8: Cố định nhãn đỉnh A sửa lại các đỉnh C, D, E 15
Hình 9: Cố định nhãn đỉnh E, sửa lại nhãn đỉnh F 16
Hình 10: Cố định nhãn đỉnh C, sửa lại nhãn các đỉnh F, G 16
Hình 11: Cố định nhãn đỉnh D, không sửa lại nhãn cho đỉnh nào 16
Hình 12: Cố định nhãn cho đỉnh F, sửa nhãn các đỉnh G, B 17
Hình 13: Cố định nhãn G, sửa lại nhãn đỉnh B 17
Hình 14: Cố định nhãn đỉnh B, kết thức thuật toán 17
Hình 15: Đồ thị minh họa 27
Hình 16: Minh họa cho file graph.txt 27
Hình 17: Kết quả chạy chương trình 28
Hình 18: Đồ thị minh họa 28
Hình 19: Kết quả chương trình 29
Trang 5Để biểu diễn đồ thị ta sử dụng ma trận trọng số C= {c[i,j], i,j=1, 2, .,n} với c[i,j]= c(i,j) nếu (i,j) Є E và c[i,j]= nếu (i,j) E trong đó số có thể được đặt bằng một trong các giá trị sau: 0, +, -
Một đồ thị có trọng số có thể được biểu diễn dưới dạng danh sách các đỉnh và các cạnh, mỗi cạnh đi kèm với một giá trị số liệu (trọng số) Ví dụ, một đồ thị có trọng số
có thể được mô tả như sau:
Ví dụ 2:
Hình 1: Đồ thị minh họa
Trang 6
2 Ưu nhược điểm của phương pháp biểu diễn đồ thị có trọng số
• Ưu điểm lớn nhất của phương pháp biểu diễn đồ thị có trọng số là để trả lời câu hỏi: Hai đỉnh u,v có kề nhau trên đồ thị hay không, chúng ta chỉ phải thực hiện một phép so sánh
• Nhược điểm lớn nhất của phương pháp này là: không phụ thuộc vào số cạnh của
đồ thị, ta luôn phải sử dụng n2 đơn vị bộ nhớ để lưu trữ ma trận kề của nó
3 Ứng dụng
Đồ thị có trọng số có rất nhiều ứng dụng trong thực tế do khả năng mô hình hóa các mối quan hệ phức tạp giữa các đối tượng và mối quan hệ này được đo lường thông qua các trọng số Dưới đây là một số ứng dụng phổ biến của đồ thị có trọng số:
• Mạng Lưới Giao Thông: Một trong những ứng dụng phổ biến nhất của đồ thị có trọng số là tối ưu hóa đường đi trong hệ thống giao thông Trọng số có thể đại diện cho thời gian di chuyển, khoảng cách hoặc chi phí
• Định Tuyến Mạng Máy Tính: Trong các mạng máy tính, đồ thị có trọng số được
sử dụng để xác định đường dẫn tối ưu dựa trên các yếu tố như băng thông, độ trễ
và chi phí
• Quy hoạch Tài Nguyên: Các hệ thống quản lý tài nguyên, chẳng hạn như quản lý nguồn nước hoặc năng lượng, có thể sử dụng đồ thị có trọng số để tối ưu hóa việc
sử dụng tài nguyên dựa trên các yếu tố như chi phí và hiệu suất
• Lộ Trình Tài Chính: Trong lĩnh vực tài chính, đồ thị có thể được sử dụng để mô hình hóa mối quan hệ giữa các tài sản và tối ưu hóa việc đầu tư dựa trên lợi nhuận
dự kiến và rủi ro
• Hệ Thống Điều Khiển và Điều Tiết: Trong các hệ thống tự động hóa và điều khiển, đồ thị có trọng số có thể được sử dụng để mô phỏng các mối quan hệ giữa các biến và tối ưu hóa các giá trị đo lường
• Tìm Kiếm Web và Xếp Hạng Trang Web: Trong công cụ tìm kiếm web, các trang web và liên kết giữa chúng có thể được mô hình hóa bằng đồ thị có trọng số để cải thiện kết quả tìm kiếm Đồng thời, xếp hạng trang web cũng có thể được xây dựng dựa trên các đồ thị có trọng số
• Mạng Xã Hội: Trong các mạng xã hội, mối quan hệ giữa người dùng hoặc nhóm người dùng có thể được mô hình hóa thông qua đồ thị có trọng số, với các trọng
số đại diện cho mức độ tương tác hoặc tầm ảnh hưởng giữa họ
Trang 7Đồ thị có trọng số được sử dụng rộng rãi trong nhiều ứng dụng thực tế như mạng lưới giao thông, hệ thống điều khiển, quản lý tài nguyên, tìm kiếm web, xếp hạng trang web,
và nhiều lĩnh vực khác, nơi mà việc biết được trọng số của các liên kết giữa các đối tượng là quan trọng để ra quyết định hoặc tối ưu hóa các yếu tố nhất định
II Bài toán đường đi ngắn nhất
1 Phát biểu bài toán
- Cho đồ thị có hướng G =t(V,E) với hàm trọng số w: Et→ R (w(e) được gọi là độ dài hay trọng số của cạnh e)
- Độ dài của đường đi P = v 1t→ v 2 → … → v k là số
- Đường đi ngắn nhất xuất phát từ đỉnh u đến đỉnh v là đường đi có độ dài ngắn nhất trong số các đường đi nối u với v
- Độ dài của đường đi ngắn nhất từ u đến v còn được gọi là khoảng cách từ u tới v
Trang 8- Giao thông (Transportation)
- Truyền tin trên tmạng (Network routing) (cần hướng các gói tin đến đích trên mạng theo đường nào?)
- Truyền thông (Telecommunications)
- Speech interpretation (best interpretation of a spoken sentence)
- Điều khiển robot (Robot path planning)
- Medical imaging
- Giải các bài toán phức tạp hơn trên mạng
3 Các dạng bài toán đường đi ngắn nhất
- Bài toán một nguồn một đích: Cho hai đỉnh s và t, cần tìm đường đi ngắn nhất từ s đến
t
- Bài toán một nguồn nhiều đích: Cho s là đỉnh nguồn, cần tìm đường đi ngắn nhất từ s đến tất cả các đỉnh còn lại
- Bài toán mọi cặp: Tìm đường đi ngắn nhất giữa mọi cặp đỉnh của đồ thị
- Đường đi ngắn nhất theo số cạnh - BFS
Trang 9Chương 2: Thuật toán DIJKSTRA
I Giới thiệu về thuật toán DIJKSTRA
1 Khái niệm
Thuật toán Dijkstra là một thuật toán trong lĩnh vực đồ thị được phát triển bởi nhà toán học người Hà Lan Edsger W Dijkstra vào năm 1956 Thuật toán này được sử dụng để tìm đường đi ngắn nhất từ một đỉnh nguồn đến tất cả các đỉnh còn lại trong đồ thị có trọng số dương Dijkstra còn gọi là "giải thuật tìm kiếm theo chiều rộng có trọng số" hoặc "giải thuật tìm đường đi ngắn nhất."
Dijkstra hoạt động như sau:
• Khởi tạo một mảng kết quả để lưu trữ khoảng cách ngắn nhất từ đỉnh nguồn đến tất cả các đỉnh khác ban đầu Ban đầu, khoảng cách từ đỉnh nguồn đến chính nó
• Lặp lại bước 3 cho đến khi tập hợp chưa được xem xét trở thành rỗng hoặc cho đến khi tất cả các đỉnh đã được xem xét
• Khi thuật toán kết thúc, bạn sẽ có các khoảng cách ngắn nhất từ đỉnh nguồn đến tất cả các đỉnh trong đồ thị
Thuật toán Dijkstra thường được sử dụng trong các ứng dụng liên quan đến tìm đường
đi ngắn nhất trong mạng lưới giao thông, định tuyến mạng máy tính, và nhiều lĩnh vực khác Tuy nhiên, nó chỉ hoạt động cho đồ thị có trọng số dương và không xử lý đường
đi trên đồ thị có trọng số âm Để xử lý đường đi với trọng số âm, thuật toán Ford thích hợp hơn
Trang 10• Sử dụng hàng đợi ưu tiên (priority queue): Dijkstra thường sử dụng một hàng đợi
ưu tiên để duyệt các đỉnh và cập nhật khoảng cách tạm thời Điều này giúp cho việc xử lý các đỉnh gần nhất trước, giúp tối ưu hóa thời gian chạy của thuật toán
• Tối ưu cho đường đi từ một đỉnh nguồn đến tất cả các đỉnh khác: Dijkstra được thiết kế để tìm đường đi ngắn nhất từ một đỉnh nguồn đến tất cả các đỉnh còn lại trong đồ thị Điều này làm cho nó hữu ích trong các tình huống như định tuyến mạng lưới giao thông hoặc tìm đường đi trong các ứng dụng tương tự
• Thuật toán tham lam (greedy algorithm): Dijkstra là một thuật toán tham lam, có nghĩa là nó luôn chọn đỉnh gần nhất có khoảng cách tạm thời ngắn nhất để xem xét tiếp theo Điều này đảm bảo rằng nó sẽ tìm ra đường đi ngắn nhất từ đỉnh nguồn đến tất cả các đỉnh khác
• Thời gian chạy tương đối nhanh: Dijkstra có thời gian chạy tương đối nhanh và hoạt động hiệu quả trên đồ thị nhỏ và trung bình Tuy nhiên, trên đồ thị lớn, nó
có thể trở nên không hiệu quả và yêu cầu sử dụng các biến thể hoặc thuật toán khác như thuật toán A* để tối ưu hóa hiệu suất
3 Yêu cầu cơ bản để thực hiện thuật toán
Để thực hiện thuật toán Dijkstra để tìm đường đi ngắn nhất trong một đồ thị, bạn cần thực hiện một số yêu cầu cơ bản:
• Đồ thị vô hướng hoặc hướng: Dijkstra có thể hoạt động trên cả đồ thị vô hướng (undirected) và đồ thị hướng (directed) Bạn cần xác định loại đồ thị bạn đang làm việc với và cung cấp thông tin về các cạnh và trọng số của chúng
• Trọng số dương: Đồ thị phải có các cạnh có trọng số dương Dijkstra không thích hợp để xử lý đồ thị có cạnh có trọng số âm
• Đỉnh nguồn: Bạn cần xác định đỉnh nguồn, từ đó bạn muốn tìm đường đi ngắn nhất đến tất cả các đỉnh còn lại trong đồ thị
• Cấu trúc dữ liệu lưu trữ: Để thực hiện Dijkstra, bạn cần một cấu trúc dữ liệu để lưu trữ các khoảng cách tạm thời từ đỉnh nguồn đến tất cả các đỉnh khác, thông thường sử dụng một mảng hoặc danh sách
• Hàng đợi ưu tiên: Để tối ưu hóa thuật toán, bạn cần sử dụng một hàng đợi ưu tiên
để duyệt các đỉnh và cập nhật khoảng cách tạm thời Hàng đợi ưu tiên giúp bạn luôn chọn đỉnh gần nhất có khoảng cách tạm thời ngắn nhất để xem xét tiếp theo
• Khởi tạo khoảng cách ban đầu: Bạn cần khởi tạo khoảng cách từ đỉnh nguồn đến chính nó là 0 và các khoảng cách từ đỉnh nguồn đến các đỉnh khác là vô cùng (hoặc một giá trị lớn đủ lớn để đại diện cho vô cùng)
Trang 11• Xác định khi nào kết thúc: Thuật toán Dijkstra kết thúc khi tất cả các đỉnh đã được xem xét hoặc khi đỉnh đích cụ thể đã được xem xét (nếu bạn chỉ quan tâm đến một đỉnh cụ thể)
• Lưu trữ đường đi: Để xác định đường đi ngắn nhất từ đỉnh nguồn đến một đỉnh đích cụ thể, bạn cần lưu trữ thông tin về cách đi từng bước trong quá trình chạy thuật toán
• Xử lý các trường hợp đặc biệt: Dijkstra có thể xử lý nhiều tình huống đặc biệt, như đồ thị không liên thông hoặc không có đường đi từ đỉnh nguồn đến một số đỉnh khác Bạn cần xác định cách xử lý những tình huống này trong mã của mình
• Lựa chọn ngôn ngữ lập trình: Bạn có thể thực hiện thuật toán Dijkstra bằng nhiều ngôn ngữ lập trình khác nhau, như Python, Java, C++, và nhiều ngôn ngữ khác Chọn một ngôn ngữ lập trình phù hợp với ứng dụng của bạn và thư viện hỗ trợ hàng đợi ưu tiên nếu cần
II Mô tả thuật toán
1 Ý tưởng thuật toán
Thuật toán Dijkstra là một thuật toán giải quyết bài toán đường đi ngắn nhất từ một đỉnh đến các đỉnh còn lại của đồ thị có hướng không có cạnh mang trọng số âm Ý tưởng của thuật toán Dijkstra là sử dụng phép duyệt lan truyền, bắt đầu duyệt từ đỉnh xuất phát, tại mỗi đỉnh tính khoảng cách từ đỉnh xuất phát đến các đỉnh kề của đỉnh đang xét, sau đó chọn đỉnh tiếp theo sao cho khoảng cách từ đỉnh đó đến đỉnh ban đầu là nhỏ nhất (so với các đỉnh kế khác), duyệt đến khi gặp được đỉnh cuối thì dừng lại hoặc không còn đỉnh kế thì dừng lại
Ý tưởng cơ bản của thuật toán như sau:
Bước 1: Từ đỉnh gốc, khởi tạo khoảng cách tới chính nó là 0, khởi tạo khoảng cách nhỏ nhất ban đầu tới các đỉnh khác là +∞ Ta được danh sách các khoảng cách tới các đỉnh
Bước 2: Chọn đỉnh a có khoảng cách nhỏ nhất trong danh sách này và ghi nhận Các lần sau sẽ không xét tới đỉnh này nữa
Bước 3: Lần lượt xét các đỉnh kề b của đỉnh a Nếu khoảng cách từ đỉnh góc tới đỉnh b nhỏ hơn khoảng cách hiện tại đang được ghi nhận thì cập nhật giá trị và đỉnh kề
a vào khoảng cách hiện tại của b
Trang 12Bước 4: Sau khi xét tất cả đỉnh kề b của đỉnh a Lúc này ta được danh sách khoảng
cách tới điểm đã được cập nhật Quay lại Bước 2 với danh sách này Thuật toán kết thúc
khi chọn được khoảng cách nhỏ nhất từ tất cả các điểm
*Trong thuật toán Dijkstra, việc đồ thị có trọng số không âm là điều kiện cần để đảm bảo tính đúng đắn của thuật toán Bởi lẽ, Dijkstra xác định đường đi ngắn nhất bằng cách tính tổng trọng số của các cạnh trên đường đi Nếu có trọng số âm, thuật toán Dijkstra không đảm bảo tìm ra kết quả chính xác, vì nó có thể bị mắc kẹt trong vòng lặp
vô hạn hoặc cho ra kết quả sai số
Hình 3: Minh họa về các bước triển khai của thuật toán Dijkstra tìm đường đi ngắn nhất
Ví dụ:Tìm đường đi ngắn nhất giữa K và L trong biểu đồ được chỉ ra trong hình bằng cách sử dụng Thuật toán Dijkstra
Trang 13Hình 4: Đồ thị minh họa
2 Phương pháp thuật toán
Bước 1: Đưa đỉnh K là S và xác định tất cả các đường đi trực tiếp từ K đến tất cả các
đỉnh khác mà không đi qua đỉnh nào khác
Khoảng cách đến tất cả các đỉnh khác
Bước 2: Đưa đỉnh trong S gần K nhất và xác định đường đi ngắn nhất đến tất cả các
đỉnh qua đỉnh này và cập nhật các giá trị Đỉnh gần nhất là c
Trang 14Vì n-1 đỉnh thuộc S Do đó ta tìm được khoảng cách ngắn nhất từ K đến tất cả các đỉnh khác Như vậy, khoảng cách ngắn nhất giữa K và L là 8 và đường đi ngắn nhất là K, c,
Trang 154 Lưu đồ thuật toán
Hình 5: Lưu đồ thuật toán Dijkstra
5 Ví dụ và chứng minh thuật toán
5.1 Ví dụ minh họa
Cho đồ thị sau đây, tìm đường đi ngắn nhất từ a tới b
Trang 16Hình 6: Đồ thị minh họa
Ta minh họa các bước của thuật toán bằng đồ thị:
Hình 7: Gắn cho A nhãn 0, các nhãn khác có nhãn là +oo
Trang 17
Hình 9: Cố định nhãn đỉnh E, sửa lại nhãn đỉnh F
Hình 10: Cố định nhãn đỉnh C, sửa lại nhãn các đỉnh F, G
Hình 11: Cố định nhãn đỉnh D, không sửa lại nhãn cho đỉnh nào
Trang 195.2 Chứng minh thuật toán
5.2.1 Phép chứng minh trực tiếp
Hiển nhiên thuật toán luôn dừng
Ta tiến hành phân tích thuật toán thành những bước sau:
Bước 1:
+ Gán đỉnh cho đỉnh a nhãn L(a) = 0, các dinh còn lai cé nhàn là +∞
+ Tập S các đỉnh có nhãn cố định ban đầu được gán bằng rỗng
+ Trong các đỉnh y kề với x và đang có nhãn tạm thời ta thực hiện:
Nếu L(y) > L(x) + G(x, y) thì gán lại L(y) = L(x) + G(x, y)
Tại các thời điểm mà L(y) được gắn nhãn lại thì giá trị của nó chỉ có giảm đi mà thôi Vậy khi kết thúc thuật toán với tất cả các nhãn x được cố định trước không tồn tại đỉnh L(y) > L(x) + G(x, y) Điều này đồng nghĩa khi kết thúc thuật toán thì L(y) ≤ L(x) + G(x, y) Từ đây suy ra khi kết thúc thuật toán thì G(x, y) ≥ L(y) - L(x)
Bây giờ ta chỉ xác định đường đi ngắn nhất từ a tới b do việc xác định các đường đi ngắn nhất xuất phát từ a tới các đỉnh khác hoàn toàn tương tự
Khi thuật toán kết thúc, ta xác định được đỉnh u1 kề b có tính chất: L(b) = L(u1)+G(u1,b)
Đỉnh u1 như thế luôn tồn tại vì L(b) giảm dần trong quá trình tính toán còn u1, chính là đỉnh cuối cùng để giảm L(b) Từ đây suy ra:
G(u1, b) = L(b) - L(u1)
Tương tự ta cùng tìm được đỉnh u2 kề u1 sao cho L(u1) = L(u2) + G(u1, u2)…
Dãy L(b), L(u1), L(u2), , Giảm dần thực sự, vì vậy, đến một lúc nào đó sẽ có L(uk+1) =
0, tức uk+1=a