Thuật toán A* có những ưu điểm quan trọng như tính tối ưu và tính đầy đủ. Tuy nhiên, nếu hàm heuristic không tốt, thuật toán sẽ phải xem xét nhiều trạng thái và có yêu cầu bộ nhớ trong trường hợp xấu nhất là O(bm). Yêu cầu bộ nhớ theo hàm mũ như vậy làm giảm khả năng sử dụng A*. Để giải quyết vấn đề này có thể sử dụng phiên bản của A* được gọi là A* sâu dần (Iterative Deepening A*) có yêu cầu bộ nhớ tỷ lệ tuyến tính với độ sâu.
Phương pháp: Nguyên tắc của A* sâu dần là lặp lại việc tìm kiếm theo chiều sâu trên các cây tìm kiếm con có giá trị hàm f(n) không lớn hơn các ngưỡng 0, α, 2α, 3α, .v.v..
Cụ thể:
1. Tìm kiếm sâu dần (DFS), không mở rộng nút có hàm f > 0, nếu tìm được đích thì dứng lại. 2. Tìm kiếm sâu dần (DFS), không mở rộng nút có hàm f > α, nếu tìm được đích thì dứng lại. 2. Tìm kiếm sâu dần , không mở rộng nút có hàm f > 2α, nếu tìm được đích thì dứng lại.
Ở đây, α là giá trị được thêm vào ngưỡng sau mỗi vòng lặp. Để mỗi vòng lặp có thể xét thêm các nút mới α cần có giá trị lớn hơn hoặc bằng giá thành nhỏ nhất để di chuyển giữa hai trạng thái trong không gian tìm kiếm. Ởđây cần lưu ý cách chọn α. Nếu α nhỏ, sau mỗi lần tăng ngưỡng, cây tìm kiếm mới sẽ thêm được ít nút do với cây tìm kiếm cũ và do vậy cần lặp lại quá trình tìm sâu nhiều lần, dẫn tới tăng độ phức tạp tính toán. Ví dụ, trong trường hợp đặc biệt, khi giá trị của f(n) trên mọi nút đều khác nhau, mỗi bước lặp sẽ chỉ xem xét thêm được một nút so với bước trước. Khi đó, nếu A* cần mở rộng N nút, thì A* sâu dần sẽ phải mở rộng 1+2+…+N = O(N2).
Giải pháp cho vấn đề độ phức tạp tính toán là sử dụng mức độ tăng ngưỡng β > α, sao cho tại mỗi bước lặp sẽ mở rộng cây tìm kiếm thêm một số nút mới. Giá trịβ như vậy cho phép giảm thời gian tìm kiếm, tuy nhiên chỉ trả lại lời giải β-tối ưu trong trường hợp xấu nhất, tức là nếu thuật toán tìm được lời giải m* thì ta có g(m*) < g* + β.
Thuật toán A* sâu dần chi tiết được thể hiện trên hình dưới đây:
Thuật toán: A*(Q, S, G, P, c, h)
• Đầu vào: bài toán tìm kiếm, hàm heuristic h
• Đầu ra: đường đi ngắn nhất từ nút xuất phát đến nút đích
• Khởi tạo: danh sách các nút biên (nút mở) O ← S giá trị i = 0 là ngưỡng cho hàm f While(1) do
1. while (O không rỗng) do a) Lấy nút n từđầu O
b) Nếu n thuộc G, return(đường đi tới n) c) Với mọi m ∈ P(n)
i. g(m) = g(n) + c(m, n) ii. f(m) = g(m) + h(m)
iii. If f(m) ≤ i then Thêm m vào đầu O 2. i ← i + β, O ← S
Hình 2.10. Thuật toán A* sâu dần
Tính chất:
• Yêu cầu bộ nhớ tuyến tính (chỉ nhớ nhánh, tương đương sâu dần)
• Độ phức tạp tính toán lớn hơn của thuật toán A*
• Không phụ thuộc vào h(n) (sau mỗi lần tăng lại làm lại từđầu → không sử dụng h(n) để
thu hẹp nhánh cần tìm).