Tưởng trực quan

Một phần của tài liệu Chuyên đề thuật toán đồ thị trong lập trình căn bản (Trang 56 - 58)

Xét bài toán tìm đường - bài toán mà A* thường được dùng để giải. A* xây dựng tăng dần tất cả các tuyến đường từ điểm xuất phát cho tới khi nó tìm thấy một đường đi chạm tới đích. Tuy nhiên, cũng như tất cả các thuật toán tìm kiếm có thông tin (informed tìm kiếm thuật toán), nó chỉ xây dựng các tuyến đường "có vẻ" dẫn về phía đích.

Để biết những tuyến đường nào có khả năng sẽ dẫn tới đích, A* sử dụng một "đánh giá heuristic" về khoảng cách từ điểm bất kỳ cho trước tới đích. Trong trường hợp tìm đường đi, đánh giá này có thể là khoảng cách đường chim bay - một đánh giá xấp xỉ thường dùng cho khoảng cách của đường giao thông.

Điểm khác biệt của A* đối với tìm kiếm theo lựa chọn tốt nhất là nó còn tính đến khoảng cách đã đi qua. Điều đó làm cho A* "đầy đủ" và "tối ưu", nghĩa là, A* sẽ luôn luôn tìm thấy đường đi ngắn nhất nếu tồn tại một đường đi như thế. A* không đảm bảo sẽ chạy nhanh hơn các thuật toán tìm kiếm đơn giản hơn. Trong một môi trường dạng mê cung, cách duy nhất để đến đích có thể là trước hết phải đi về phía xa đích và cuối cùng mới quay lại. Trong trường hợp đó, việc thử các nút theo thứ tự "gần đích hơn thì được thử trước" có thể gây tốn thời gian.

Mô phỏng thuật toán tìm kiếm A* ứng dụng trong tìm đường đi từ một nút bắt đầu đến một nút mục tiêu trong chuyển động robot. Các vòng rỗng đại diện cho các nút trong tập mở, nghĩa là những nút đợi, và những vòng tròn tô màu là thuộc tập đóng. Màu trên mỗi nút tô màu tượng trưng cho khoảng cách từ nút đó đến điểm xuất phát: càng xanh thì

càng xa. Đầu tiên ta có thể thấy A* di chuyển theo hướng thẳng đến mục tiêu, sau khi gặp vật cản, nó sẽ tìm các đường thay thế từ các nút chờ

trong tập mở.

nghĩa là tổng trọng số của các cạnh đã đi qua. là hàm đánh giá heuristic về chi phí nhỏ nhất để đến đích từ . Ví dụ, nếu "chi phí" được tính là khoảng cách đã đi qua, khoảng cách đường chim bay giữa hai điểm trên một bản đồ là một đánh giá heuristic cho khoảng cách còn phải đi tiếp.

Hàm có giá trị càng thấp thì độ ưu tiên của càng cao (do đó có thể sử dụng một cấu trúc heap tối thiểu để cài đặt hàng đợi ưu tiên này)

function A*(điểm_xuất_phát,đích)

var đóng:= tập rỗng

var q:= tạo_hàng_đợi(tạo_đường_đi(điểm_xuất_phát)) while q không phải tập rỗng

var p:= lấy_phần_tử_đầu_tiên(q) var x:= nút cuối cùng của p if x in đóng continue if x = đích return p bổ sung x vào tập đóng foreach y in các_đường_đi_tiếp_theo(p) đưa_vào_hàng_đợi(q, y) return failure

Trong đó, các_đường_đi_tiếp_theo(p) trả về tập hợp các đường đi tạo bởi việc kéo dài p thêm một nút kề cạnh. Giả thiết rằng hàng đợi được sắp xếp tự động bởi giá trị của hàm .

"Tập hợp đóng" (đóng) lưu giữ tất cả các nút cuối cùng của p (các nút mà các đường đi mới đã được mở rộng tại đó) để tránh việc lặp lại các chu trình (việc này cho ra thuật toán tìm kiếm theo đồ thị). Đôi khi hàng đợi được gọi một cách tương ứng là "tập mở". Tập đóng có thể được bỏ qua (ta thu được thuật toán tìm kiếm theo cây) nếu ta đảm bảo được rằng tồn tại một lời giải hoặc nếu hàm các_đường_đi_tiếp_theo được chỉnh để loại bỏ các chu trình.

Giải thuật tìm kiếm A* 55

Một phần của tài liệu Chuyên đề thuật toán đồ thị trong lập trình căn bản (Trang 56 - 58)