Lecture 6 — BFS & DFS (+ C-space)

Chương B** · tìm đường trên đồ thị / lưới — nền hierarchical path & gridworld

Lecture 6 — BFS & DFS (+ C-space)

Chương B · tìm đường trên đồ thị / lưới — nền hierarchical path & gridworld


Khung 6 câu hỏi

# Câu hỏi Trả lời ngắn
1 Tại sao cần? Máy đã ổn định (Ch.A) nhưng phải tới goal mà không đụng — cần tìm đường có hệ thống.
2 So với cái khác? Vs Dijkstra/A*: BFS tối ưu số bước khi cạnh đồng giá. Vs RRT: lưới/rời rạc vs lấy mẫu liên tục. Vs RL: planner giải từng map; RL amortize.
3 Giải quyết gì & thế nào? Đưa robot về điểm trong C-space (phồng vật cản); BFS loang lớp; DFS đào sâu.
4 Kết quả ra sao? Dãy ô/waypoint; nền hierarchical RL tầng cao.
5 Nên dùng khi nào? Lưới thấp chiều, cạnh đều; sanity path; gridworld.
6 Không nên khi nào? 12D liên tục (curse of dimensionality → RRT); cần tối ưu cost khác nhau (→ Dijkstra/A*).

🖼️ Hình nhanh: C-space = phồng vật cản → robot thành một điểm; BFS = vết dầu; DFS = chuột chui hang.

Hình minh họa (seminar-ready)

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.

C-space phồng vật cản theo bán kính UAV.
C-space phồng vật cản theo bán kính UAV.HiếuTC · gốc
Hẻm đô thị — quên phồng tường là xước cánh.
Hẻm đô thị — quên phồng tường là xước cánh.Generated for ebook · seminar OK
  Workspace thật:          C-space (robot = điểm):
     drone ○    cột ●         điểm ·    đĩa phồng ████
        ○──x──●                  ·······████████
                                 ·······████████  ★ tránh R+r

  BFS (queue): loang lớp đều     DFS (stack): lao một hướng
     S → 1 → 2 → 3                  S →↓→↓→ cụt → lùi

0. Mục tiêu học

  1. Giải thích C-space và vì sao robot được xem như một điểm.
  2. Chạy được BFS; nêu điều kiện tối ưu (cạnh đồng giá).
  3. Phân biệt BFS vs DFS (FIFO vs LIFO; tối ưu độ dài vs không).
  4. Hiểu curse of dimensionality → lý do tồn tại RRT (Lec 8).

1. Trực giác — nói bằng lời thường

Thay vì nghĩ “drone hình khối bay giữa tường hẻm / cột điện phố”, nghĩ: một điểm di chuyển trong không gian cấu hình, nơi vật cản đã được phồng đúng bằng kích thước robot + margin an toàn.

Drone bán kính \(r\) tránh tường/cột bán kính \(R\) ⇔ điểm tránh đĩa bán kính \(R+r\) (thường cộng thêm \(\delta\) gió / sai ước lượng). Từ đây mọi thuật toán chỉ làm việc với điểm.

  • BFS = loang như vết dầu trên mặt nước đọng: từ start lan đều từng lớp, lớp nào chạm goal thì xong — đường ít cạnh nhất nếu mọi bước giá bằng nhau.
  • DFS = chuột chui hang: lao sâu một hướng đến cùng, cụt thì lùi — kiểm tra liên thông được, không đảm bảo đường ngắn.

🇻🇳 Chuyện thật (sân B): Hẻm Hà Nội / ngõ HCM hẹp — tường “thật” chỉ cách nhau vài mét, nhưng drone có cánh quạt và cần margin.
Phồng tường theo \(R_{\text{drone}}+r_{\text{margin}}\) trong C-space: lối từng tưởng đi được biến thành hành lang hẹp hoặc đứt đoạn trên lưới.
BFS trên lưới đó trả path ít bước; quên phồng thì path “đẹp trên bản đồ” vẫn quẹt mái tôn lúc bay.
Chốt: C-space = phồng vật cản; planner chỉ thấy điểm — clearance trên chuyến bay đã được nướng vào bản đồ trước khi loang. Chi tiết sân: ../00C.


2. Cốt lõi kỹ thuật

2.1 Đồ thị

\(G=(V,E)\): đỉnh = cấu hình rời rạc, cạnh = bước hợp lệ (không đụng C-obstacle).

Thuật toán Cấu trúc Tối ưu khi nào Dùng chính
BFS queue FIFO cạnh đồng giá → ít cạnh nhất path ngắn trên lưới đều
DFS stack LIFO không tối ưu độ dài liên thông / search sâu

Cả hai cần tập visited — quên là lặp vô hạn. Độ phức tạp BFS: \(O(|V|+|E|)\).

2.2 Curse of dimensionality

Lưới \(k\) ô/chiều, \(n\) chiều → \(k^n\) đỉnh. Quadrotor 12D × 100 ô/chiều = \(10^{24}\) — bất khả thi. → Lec 8 sampling.

2.3 ASCII — BFS loang (Sơ đồ)

  bước 0          bước 3              hoàn tất (số = lớp)
  S . . . #       S 1 2 3 #           S 1 2 3 #
  . . . . .       1 2 3 . .           1 2 3 4 5
  . # # . .  →    2 # # . .     →     2 # # 5 6
  . . . . .       3 . . . .           3 4 5 6 7
  . . . G .       . . . G .           4 5 6 7 G
                                      ★ lần ngược parent  G→…→S

3. Demo — BFS trên lưới

"""BFS trên lưới: tìm path S→G, tránh #.
Ý tưởng: loang từng lớp; lưu parent để lần ngược đường đi.
"""
from collections import deque

grid = ["S...#", ".....", ".##..", ".....", "...G."]
R, C = len(grid), len(grid[0])

# 1) Tìm tọa độ start/goal
start = goal = None
for r in range(R):
    for c in range(C):
        if grid[r][c] == "S":
            start = (r, c)
        if grid[r][c] == "G":
            goal = (r, c)

# 2) BFS: parent[node] = nút trước (vừa là visited)
parent = {start: None}
q = deque([start])
found = False
while q:
    cur = q.popleft()
    if cur == goal:
        found = True
        break
    for dr, dc in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
        nxt = (cur[0] + dr, cur[1] + dc)
        if not (0 <= nxt[0] < R and 0 <= nxt[1] < C):
            continue
        if grid[nxt[0]][nxt[1]] == "#":
            continue
        if nxt in parent:
            continue
        parent[nxt] = cur
        q.append(nxt)

# 3) Lần ngược
path, node = [], goal if found else None
while node is not None:
    path.append(node)
    node = parent[node]
path.reverse()
print("Tìm thấy?", found)
print("Đường (r,c):", path)
print("Độ dài (số cạnh):", len(path) - 1)

🧪 Kỳ vọng demo:
- Tìm thấy? True
- Một dãy ô từ S tới G (ví dụ đi vòng #).
- Độ dài = số bước tối thiểu trên lưới 4-hướng (cạnh đồng giá).
★ Đổi # hoặc goal → path đổi; quên parent/visited → có thể treo.


4. Gắn RL–UAV / path-planning đa mục tiêu của bạn

  • Lưới + BFS = gridworld trong sách RL — cùng cấu trúc đồ thị.
  • Hierarchical: tầng cao chọn waypoint trên đồ thị thưa (bài này); tầng thấp PD/LQR/RL liên tục.
  • C-space “phồng vật cản” → khi viết reward phạt va chạm: phạt theo khoảng cách tới C-obstacle, không phải bề mặt hình học thô.
  • Độ phủ: cell coverage có thể là đỉnh đồ thị; BFS/Dijkstra trên dual graph ô chưa thăm.
  • Gió / năng lượng: cạnh chưa đồng giá → sang Lec 7 (cost map).
  • 12D full state không lưới hóa — đừng cố BFS trong state đầy đủ.

5. Ưu / nhược (câu 5–6)

✅ Nên ❌ Không Phủ / gió / pin
BFS Lưới thấp chiều, cạnh đều Cost gió–pin khác nhau Chỉ tối ưu số bước
DFS Kiểm tra liên thông Path chính khi cần ngắn Dễ đường vòng vô ích
C-space Phồng \(R+r\) nhất quán sim–reward Robot điểm vs phạt theo vật thật lệch An toàn coverage
Lưới cao chiều 12D × nhiều ô → RRT

6. Lỗi thường gặp

  • ⚠️ Phạt va chạm theo kích thước vật thật nhưng sim robot như điểm — không nhất quán C-space.
  • ⚠️ Dùng DFS như thuật toán tìm đường chính khi cạnh đồng giá — quên không tối ưu độ dài.
  • ⚠️ Cố lưới hóa không gian 12D rồi ngạc nhiên hết RAM / không xong.

7. Checklist

  1. C-space là gì — vì sao robot thành một điểm?
  2. BFS tối ưu theo nghĩa nào, dưới điều kiện gì?
  3. DFS dùng chính khi nào trong planning?
  4. Vì sao lưới hóa khó sống ở không gian 12 chiều?

Nhớ một câu: C-space phồng vật cản; BFS = ít bước nhất khi cạnh đều; chiều cao → đừng lưới hóa, hãy sampling.

🔗 Sang bài sau mang theo: Cạnh thực tế có giá gió/pin khác nhau → Lec 7 Dijkstra / A* với heuristic admissible.


Trước: Lec05 · Sau: Lec07 — Dijkstra & A*