Ebook Robotics · RL–UAV
Lecture 7 — Dijkstra & A*
Chương B** · đường *rẻ nhất* (gió · pin · cấm mềm) — không chỉ ít bước
Chế độ Slide · phím ← → · F toàn màn · Esc về đọc · S mở slide
Chương B** · đường *rẻ nhất* (gió · pin · cấm mềm) — không chỉ ít bước
Chương B · đường rẻ nhất (gió · pin · cấm mềm) — không chỉ ít bước
| # | Câu hỏi | Trả lời ngắn |
|---|---|---|
| 1 | Tại sao cần? | Thực tế cạnh có giá khác nhau (xa, gió, cấm bay mềm, tốn pin) — BFS không đủ. |
| 2 | So với cái khác? | Vs BFS: tối ưu theo cost. Vs A* vs Dijkstra: A* có \(h\) hướng về goal. Vs RL: \(h\) ≈ value; A* search có bảo đảm khi admissible. |
| 3 | Giải quyết gì & thế nào? | Dijkstra pop theo \(g\); A* theo \(f=g+h\) với \(h\) admissible. |
| 4 | Kết quả ra sao? | Path + cost*; dùng làm baseline / oracle / cost map cho reward. |
| 5 | Nên dùng khi nào? | Đồ thị/lưới có cost; cần tối ưu hoặc gần tối ưu; thấp–trung bình chiều. |
| 6 | Không nên khi nào? | Giá cạnh âm (Dijkstra); \(h\) inadmissible mà vẫn claim tối ưu; không gian liên tục cao chiều (→ RRT). |
🖼️ Hình nhanh: Dijkstra = nước lan địa hình (chỗ rẻ ngập trước); A* = có la bàn dồn về goal.
Hình gốc hoặc minh họa cho ebook — không cắt từ slide Princeton. Dùng Present: bật Slide · F toàn màn.
Dijkstra mở rộng: A* mở rộng:
· · · · ·
· · · · · · · · · ·
· · · S · · · · S · · · · · · · ► G
· · · · · · · · · ·
· · · · · ► G
(tròn đều, tốn nút) (giọt nước về goal, tiết kiệm)
f = g + h g = cost-to-come h = ước lượng cost-to-go
Trên bản đồ đồi chè, “mét đường chim bay” thường là lời nói dối dễ thương: leo dốc và ngược gió đắt pin hơn đi ngang đường đồng mức.
🇻🇳 Chuyện thật (sân A): Quét phủ đồi chè Thái Nguyên / Mộc Châu: cạnh đi ngược gió sườn hoặc leo thẳng dốc phải mang cost cao hơn cạnh đi ngang đường đồng mức — dù mét ngắn hơn.
Dijkstra / A* với \(c(e)\) gắn gió–leo–pin sẽ né “đường ngắn mà chết pin giữa thửa”; BFS đếm bước thì vẫn lao vào.
Heuristic \(h\) admissible (không ước quá thấp chi phí còn lại) giữ A* vừa tối ưu vừa ít mở nút.
Chốt: cost cạnh ≠ mét thuần; trên chuyến bay, path tối ưu năng lượng / gió đã được mã hóa trong \(g\) và \(h\). Chi tiết sân:../00C.
\[ f(n)=g(n)+h(n) \]
| BFS | Dijkstra | A* | |
|---|---|---|---|
| Tối ưu | số cạnh (cạnh đều) | cost* (≥0) | cost* nếu \(h\) admissible |
| Hướng goal | không | không | có \(h\) |
| RL analogy | uniform cost steps | cost-to-come | \(h\approx V\) dẫn đường |
Cạnh đồng giá? ──yes──► BFS
│ no
▼
Cần hướng goal / ít mở nút? ──no──► Dijkstra
│ yes
▼
Có h admissible? ──yes──► A* ──no──► đừng claim tối ưu
│
▼ cao chiều liên tục? ──► RRT (Lec 8)
"""A* trên lưới 5x5; ô giá 9 = vùng đắt (gió/cấm mềm).
So với BFS: đường có thể dài hơn theo số ô nhưng rẻ hơn theo cost.
"""
import heapq
cost = [
[1, 1, 1, 9, 1],
[1, 9, 1, 9, 1],
[1, 9, 1, 1, 1],
[1, 1, 1, 9, 1],
[9, 9, 1, 1, 1],
]
R = C = 5
start, goal = (0, 0), (4, 4)
def h(n):
# Manhattan: admissible trên lưới 4-hướng khi mọi bước cost ≥ 1
return abs(n[0] - goal[0]) + abs(n[1] - goal[1])
g = {start: 0.0}
parent = {start: None}
pq = [(h(start), start)] # f = g+h; g(start)=0
while pq:
f_cur, cur = heapq.heappop(pq)
if cur == goal:
break
for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
nb = (cur[0] + dr, cur[1] + dc)
if not (0 <= nb[0] < R and 0 <= nb[1] < C):
continue
ng = g[cur] + cost[nb[0]][nb[1]]
if ng < g.get(nb, float("inf")):
g[nb] = ng
parent[nb] = cur
heapq.heappush(pq, (ng + h(nb), nb))
path, n = [], goal
while n is not None:
path.append(n)
n = parent[n]
path.reverse()
print("Cost* =", g[goal])
print("Path =", path)
print("Gợi ý: đổi vài ô 9→1 và chạy lại — đường sẽ 'đổi ý' (cost shaping).")
🧪 Kỳ vọng demo:
-Cost*là tổng giá ô trên path (không phải chỉ số bước).
- Path thường tránh cụm ô 9 dù có thể dài hơn vài ô so với đường “ngắn hình học”.
- Đổi 9→1 → path đổi ý — đúng cảm giác cost map gió/pin.
★ Nếu dùng \(h\) inadmissible (ví dụ phóng đại Manhattan × 10) rồi vẫn nói “tối ưu” → sai.
| ✅ Nên | ❌ Không | Năng lượng / gió / phủ | |
|---|---|---|---|
| Dijkstra | Cost map, không có \(h\) tốt | Cạnh âm | Baseline cost* |
| A* | \(h\) admissible (Manhattan/Euclid phù hợp) | Claim tối ưu khi \(h\) phóng đại | Ít nút hơn khi phủ rộng |
| Weighted A* | Replan nhanh | Cần chứng minh tối ưu chặt | Trade-off tốc độ–pin path |
| vs RL | Oracle trên map tĩnh | Thay thế policy đa map | RL amortize phân phối map |
⚡ Nhớ một câu: A* = Dijkstra có la bàn \(h\); tối ưu khi \(h\) admissible — và \(h\) chính là value xấp xỉ.
🔗 Sang bài sau mang theo: Lưới/A* chết ở chiều cao liên tục → Lec 8 RRT: sample → nearest → steer → collision check.
Trước: Lec06 · Sau: Lec08 — RRT