✨Thuật toán Dijkstra

Thuật toán Dijkstra

Thuật toán Dijkstra, mang tên của nhà khoa học máy tính người Hà Lan Edsger Dijkstra vào năm 1956 và ấn bản năm 1959, 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ố không âm. Thuật toán thường được sử dụng trong định tuyến với một chương trình con trong các thuật toán đồ thị hay trong công nghệ Hệ thống định vị toàn cầu (GPS).

Lịch sử

Đâu là con đường ngắn nhất để đi từ Rotterdam đến Groningen, hay nói chung: từ thành phố này đến thành phố nhất định. Đây là thuật toán tìm đường đi ngắn nhất, mà tôi đã thiết kế trong khoảng hai mươi phút. Vào một buổi sáng đi mua sắm ở Amsterdam cùng vị hôn thê trẻ tuổi với sự mệt mỏi, chúng tôi ngồi trên sân thượng để uống một tách cà phê và tôi chỉ nghĩ liệu tôi có thể làm điều này không, và sau đó tôi đã thiết kế thuật toán tìm đường đi ngắn nhất. Như tôi đã nói, đó là một phát minh trong hai mươi phút. Trên thực tế, nó đã được xuất bản vào năm 1959, ba năm sau đó. Các ấn phẩm vẫn có thể đọc được, quả thật như vậy, và khá đẹp. Một trong những lý do khiến nó rất hay là tôi đã thiết kế nó mà không cần bút chì và giấy. Sau này tôi đã học được rằng một trong những lợi thế của việc thiết kế mà không cần bút chì và giấy là bạn gần như buộc phải tránh đi mọi sự phức tạp có thể tránh được. Cuối cùng, thuật toán đó đã trở thành một trong những nền tảng giúp tôi nổi tiếng, với sự kinh ngạc lớn của tôi.

—Edsger Dijkstra trong một cuộc phỏng vấn với Philip L. Frana, Communications of the ACM, 2001. Mục tiêu của ông là chọn cả một bài toán và giải pháp (sẽ được tạo bởi máy tính) mà những người không thuần tính toán vẫn có thể hiểu được. Ông đã thiết kế thuật toán đường đi ngắn nhất và sau đó triển khai nó cho ARMAC bằng bản đồ giao thông được đơn giản hóa một chút của 64 thành phố ở Hà Lan. Một năm sau, ông gặp một vấn đề khác từ các kỹ sư phần cứng làm việc trên máy tính tiếp theo của học viện: giảm thiểu lượng dây cần thiết để kết nối các chân trên bảng điều khiển phía sau của máy. Như một giải pháp, ông đã phát hiện lại thuật toán Prim (được biết đến trước đó với Jarník, và cũng được Prim khám phá lại). Dijkstra đã xuất bản thuật toán vào năm 1959, 2 năm sau Prim và 29 năm sau Jarník.

Bài toán

Cho một đồ thị có hướng G=(V,E), một hàm trọng số w: E → [0, ∞) và một đỉnh nguồn s. Cần tính toán được đường đi ngắn nhất từ đỉnh nguồn s đến mỗi đỉnh của đồ thị.

Ví dụ: Chúng ta dùng các đỉnh của đồ thị để mô hình các thành phố và các cạnh để mô hình các đường nối giữa chúng. Khi đó trọng số các cạnh có thể xem như độ dài của các con đường (và do đó là không âm). Chúng ta cần vận chuyển từ thành phố s đến thành phố t. Thuật toán Dijkstra sẽ giúp chỉ ra đường đi ngắn nhất chúng ta có thể đi

Trọng số không âm của các cạnh của đồ thị mang tính tổng quát hơn khoảng cách hình học giữa hai đỉnh đầu mút của chúng. Ví dụ, với 3 đỉnh A, B, C đường đi A-B-C có thể ngắn hơn so với đường đi trực tiếp A-C.

Giới thiệu thuật toán

Xét đồ thị G =(X,E) với các cạnh có trọng số không âm.

  • Dữ liệu nhập cho thuật toán là ma trận trọng số L (với qui ước L(h,k) = +∞ nếu không có cạnh nối từ đỉnh h đến đỉnh k)và hai đỉnh x,y cho trước.
  • Dữ liệu xuất là đường đi ngắn nhất từ x đến y.

Chứng minh

Ý tưởng của thuật toán được chứng minh như sau.

Chúng ta sẽ chỉ ra, khi một đỉnh v được bổ sung vào tập S, thì d[v] là giá trị của đường đi ngắn nhất từ nguồn s đến v.

Theo định nghĩa nhãn d, d[v] là giá trị của đường đi ngắn nhất trong các đường đi từ nguồn s, qua các đỉnh trong S, rồi theo một cạnh nối trực tiếp u-v đến v.

Giả sử tồn tại một đường đi từ s đến v có giá trị bé hơn d[v]. Như vậy trong đường đi, tồn tại đỉnh giữa s và v không thuộc S. Chọn w là đỉnh đầu tiên như vậy,

Mã giả

Phân tích

Với giải thuật đã mô tả ta dễ dàng thực hiện trực tiếp trên các đồ thị kích thước nhỏ, để có thể mã hóa và cài đặt hiệu quả cần đưa thêm các cấu trúc dữ liệu để sử dụng trong giải thuật.

Dữ liệu

*Hàm d(u) dùng để lưu trữ độ dài đường đi ngắn nhất từ đỉnh nguồn s đến đỉnh u. Rõ ràng d(s)= 0. Ký hiệu X^-(u) là tập tất cả các đỉnh có cạnh đi tới đỉnh u. Nếu với mọi v \in X^-(u) đã xác định được d(v) thì:

d(u)= min\{d(v)+w(v,u), v\in X^-(u)\}
. *Để tính được giá trị nhỏ nhất này, như thông thường khi khởi tạo ta phải gán cho d(v)=\infty, sau đó gặp giá trị nhỏ hơn thì thay thế lại. *Những đỉnh đã tính được d(v)hữu hạn được cho vào một hàng đợi có ưu tiên. Hàng đợi này luôn được bổ sung và sắp xếp lại nên một cấu trúc hợp lý là cấu trúc đống nhị phân (heap)... *Để theo dõi trạng thái của các đỉnh trong quá trình xét, ta dùng hàm COLOR(u) xác định với mọi v\in V. Lúc đầu các đỉnh được tô màu trắng (WHITE), khi cho vào hàng đợi nó được tô màu xám (GRAY), khi đã tính xong khoảng cách nó được tô màu đen(BLACK). *Nếu cần ghi lại đường đi ta sẽ phải dùng một hàm con trỏ PRE(u) để chỉ đỉnh đứng ngay trước đỉnh u trên đường đi ngắn nhất từ s tới u.

Thời gian chạy

Thuật toán Dijkstra bình thường sẽ có độ phức tạp là O(n^2+m). Tuy nhiên ta có thể sử dụng kết hợp với cấu trúc heap, khi đó độ phức tạp sẽ là O((m + n)log(n)), nếu dùng Fibonacci Heap thì độ phức tạp giảm xuống còn O(m + n\log n). Trong đó m là số cạnh, n là số đỉnh của đồ thị đang xét.

👁️ 1 | 🔗 | 💖 | ✨ | 🌍 | ⌚
**Thuật toán Dijkstra**, mang tên của nhà khoa học máy tính người Hà Lan Edsger Dijkstra vào năm 1956 và ấn bản năm 1959, là một thuật toán giải quyết bài toán đường đi ngắn
} ## Bối cảnh thực tế Bài toán tìm đường đi ngắn nhất giữa hai đỉnh của đồ thị liên thông có nhiều ứng dụng thực tế như: * Bài toán chọn hành trình
Bài viết này là **danh sách các thuật toán** cùng một mô tả ngắn cho mỗi thuật toán. ## Thuật toán tổ hợp ### Thuật toán tổ hợp tổng quát * Thuật toán Brent: tìm
**Thuật toán Johnson** được Donald B. Johnson tìm ra năm 1977. Thuật toán Johnson là một thuật toán giải quyết bài toán đường đi ngắn nhất giữa mọi cặp đỉnh trong đồ thị có hướng,
**Thuật toán Bellman–Ford** hay **Giải thuật Bellman–Ford** là một thuật toán tính các đường đi ngắn nhất nguồn đơn trong một đồ thị có hướng có trọng số (trong đó một số cung có thể
Trong khoa học máy tính, **thuật toán Floyd-Warshall** (còn được gọi là **thuật toán Floyd**, **thuật toán Roy-Warshall**, **thuật toán Roy-Floyd** hoặc **thuật toán WFI**) là một thuật toán để tìm đường đi ngắn nhất
Trong khoa học máy tính, **thuật toán Prim** là một thuật toán tham lam để tìm cây bao trùm nhỏ nhất của một đồ thị vô hướng có trọng số liên thông. Nghĩa là nó
**Giải thuật tham lam** (tiếng Anh: _Greedy algorithm_) là một thuật toán giải quyết một bài toán theo kiểu metaheuristic để tìm kiếm lựa chọn tối ưu địa phương ở mỗi bước đi với hy
**Edsger Wybe Dijkstra** (; 11 tháng 5 năm 1930 tại Rotterdam – 6 tháng 8 năm 2002 tại Nuenen), là nhà khoa học máy tính người Hà Lan. Ông được nhận giải thưởng Turing năm
Trong khoa học máy tính, **A*** (đọc là _A sao_) là thuật toán tìm kiếm trong đồ thị. Thuật toán này tìm một đường đi từ một nút khởi đầu tới một nút đích cho
Trong ngành khoa học máy tính, một **giải thuật tìm kiếm** là một thuật toán lấy đầu vào là một bài toán và trả về kết quả là một lời giải cho bài toán đó,
Bài này nói về từ điển các chủ đề trong toán học. ## 0-9 * -0 * 0 * 6174 ## A * AES * ARCH * ARMA * Ada Lovelace * Adrien-Marie Legendre *
nhỏ Trong lý thuyết đồ thị, **bài toán đường đi ngắn nhất nguồn đơn** là bài toán tìm một đường đi giữa hai đỉnh sao cho tổng các trọng số của các cạnh tạo nên
Lưu ý: Danh sách **thuật ngữ lý thuyết đồ thị** này chỉ là điểm khởi đầu cho những người mới nhập môn làm quen với một số thuật ngữ và khái niệm cơ bản. Bài
nhỏ|phải|Hình vẽ một đồ thị có 6 đỉnh và 7 cạnh Trong toán học và tin học, **lý thuyết đồ thị** (tiếng Anh: _graph theory_) nghiên cứu các tính chất của đồ thị. Một cách
**Tìm kiếm theo lựa chọn tốt nhất** (tiếng Anh: _Best-first search_) là một thuật toán tìm kiếm tối ưu hóa tìm kiếm theo chiều rộng bằng cách mở rộng nút hứa hẹn nhất được chọn
Hà Lan, bất chấp diện tích và dân số thực sự khiêm tốn, có một phần đóng góp đáng kể trong quá trình hình thành nên xã hội hiện đại ngày nay. Đất nước Hà
Trong khoa học máy tính, **đống** (tiếng Anh: _heap_) là một cấu trúc dữ liệu dựa trên cây thỏa mãn _tính chất đống_: nếu B là nút con của A thì khóa(A)≥khóa(B). Một hệ quả
**Kiến trúc phần mềm** của một chương trình máy tính hay một hệ thống tính toán là cấu trúc của các thành phần trong hệ thống đó. _Kiến trúc phần mềm_ bao gồm các phần
**Giao thức định tuyến OSPF (OSPF)** là một giao thức định tuyến cho các mạng Giao thức Internet (IP). Nó sử dụng thuật toán định tuyến trạng thái liên kết (LSR) và nằm trong nhóm
**Richard Ernest Bellman** (26/8/1920 – 19/3/1984) là một nhà toán học ứng dụng người Mỹ, được ghi nhớ vì phát minh ra quy hoạch động vào năm 1953, và nhiều đóng góp quan trọng trong
right|HP-12C là một máy tính dùng RPN của hãng [[Hewlett-Packard]] **Ký pháp nghịch đảo Ba Lan** (viết tắt: **RPN**) là một ký hiệu toán học trong đó dấu đi theo toán hạng. Thí dụ: trong
**TripleS** (cách điệu là **tripleS** ; ; ) là một nhóm nhạc nữ Hàn Quốc được thành lập bởi MODHAUS. Nhóm được giới thiệu với công chúng thông qua một dự án trước khi ra
Trong ngành mạng máy tính, **định tuyến** (tiếng Anh: _routing_ hay _routeing_) là quá trình chọn lựa các đường đi trên một mạng máy tính để gửi dữ liệu qua đó. Việc định tuyến được
**Định lý Pythagoras**
Tổng diện tích của hai hình vuông có cạnh là hai cạnh vuông của tam giác vuông (_a_ và _b_) bằng diện tích của hình vuông có cạnh là cạnh huyền (_c_). Trong
Trong khoa học máy tính, **luồng điều khiển** (tiếng Anh: _control flow_ hay _flow of control_) là thứ tự các câu lệnh, tập lệnh hay lời gọi hàm riêng biệt của một chương trình mệnh
**Semaphore** là một biến được bảo vệ (hay là một kiểu dữ liệu trừu tượng), tạo thành một phương pháp để hạn chế truy nhập tới tài nguyên dùng chung trong môi trường đa chương
"[[Bài toán bữa tối của các triết gia" (_Dining Philosophers_), một bài toán kinh điển về tương tranh và chia sẻ tài nguyên]] Trong ngành khoa học máy tính, **tương tranh** là một tính chất
**Microsoft Research (MSR)** là công ty con nghiên cứu của Microsoft. Công ty này được Richard Rashid lập nên vào năm 1991 với mục đích cải tiến máy tính hiện đại nhất và giải quyết