Dijkstra & Bellman-Ford — Định tuyến Google Maps
Ở bài trước, thuật toán BFS giúp bạn tìm được số trạm ít nhất từ A đến B (đồ thị không trọng số). Tuy nhiên, trên thực tế, không có hai con đường nào dài bằng nhau. Đi quốc lộ 10km chắc chắn tốn xăng và thời gian hơn đi hẻm t ắt 2km.
Làm thế nào để Google Maps hay các bộ Router mạng lưới tính toán ra được Lộ trình có tổng chi phí (khoảng cách/thời gian) thấp nhất trong hàng tỉ ngã rẽ? Chào mừng bạn đến với hai siêu thuật toán của hệ Đồ thị có trọng số: Dijkstra và Bellman-Ford.
📋 Agenda
Thời gian đọc ước tính: ~10 phút
Sau bài này, bạn sẽ:
- ✅ Hiểu được triết lý "Tham lam" (Greedy) đằng sau thuật toán Dijkstra.
- ✅ Giải thích được sự kết hợp thần thánh giữa Graph và Priority Queue (Heap).
- ✅ Tự tay vẽ lại cơ chế cập nhật bảng khoảng cách (Distance Table).
- ✅ Phân biệt được khi nào Dijkstra vô dụng và phải nhờ cậy đến Bellman-Ford (Cạnh âm).
Yêu cầu đầu vào:
- 🔹 Đã nắm vững Priority Queue (Heap), Graph, và BFS.
❓ Vấn đề Đường đi ngắn nhất
Vấn đề (Problem Statement):
Bạn đang ở Thành phố A và muốn đi đến Thành phố E.
Đường đi có các trạm trung chuyển và khoảng cách (trọng số) như sau:
- A -> B: 10km
- A -> C: 3km
- C -> B: 4km
- B -> E: 2km
Nếu dùng BFS, nó sẽ chọn đường đi 1 chặng A -> B (Mất 10km) -> Tới nơi E mất tổng 12km.
Nhưng nếu con người nhìn vào, ta thấy đi vòng A -> C -> B chỉ mất 3 + 4 = 7km. Dù tốn nhiều chặng (Nhiều Node) hơn, nhưng TỔNG chiều dài lại ngắn hơn!
Giải pháp (Solution): Thuật toán Dijkstra (Phát âm là /'daɪkstrə/). Tư tưởng của Dijkstra rất đơn giản:
- Ghi chú khoảng cách từ Điểm bắt đầu đến MỌI ĐIỂM khác là Vô cực (
Infinity). - Từ điểm đang đứng, luôn ưu tiên chọn con đường ngắn nhất có thể.
- Khi đến một điểm mới, thử tính xem: "Đi đường này có ngắn hơn đường cũ từng ghi trong sổ không?" Nếu ngắn hơn, Cập nhật lại sổ và tiếp tục đi tới.