Tìm đường thuật toán?


24

Tôi đã đăng câu hỏi này lên stack stack trước, nhưng tôi đoán không ai quan tâm đến trò chơi điện tử ở đó ...

Một số thuật toán tìm đường được sử dụng trong các loại trò chơi là gì? (Trong tất cả các loại nhân vật di chuyển, dù sao đi nữa) Dijkstra có được sử dụng rất nhiều không? Tôi nghĩ là không, vì nó không thực sự tìm ra các bước cần thực hiện ở đâu đó, phải không? Nếu tôi hiểu đúng, nó chỉ xác định đối tượng nào gần nhất. Tôi không thực sự tìm cách mã hóa bất cứ điều gì; chỉ cần thực hiện một số nghiên cứu, mặc dù nếu bạn dán mã giả hoặc một cái gì đó, điều đó sẽ ổn (tôi có thể hiểu Java và C ++). Về cơ bản, tôi đang tìm kiếm một cái nhìn tổng quan nhanh về việc tìm đường.

Tôi biết A * giống như thuật toán sử dụng trong các trò chơi 2D. Điều đó thật tuyệt vời và tất cả, nhưng còn những game 2D không dựa trên lưới thì sao? Những thứ như Age of Empires, hay Link's Awakening. Không có không gian vuông riêng biệt để điều hướng, vậy họ làm gì?

Trò chơi 3D làm gì? Tôi đã đọc điều này http://www.ai-blog.net/archives/000152.html , mà tôi nghe là một cơ quan tuyệt vời về chủ đề này, nhưng nó không thực sự giải thích CÁCH, một khi các lưới được đặt, việc tìm đường được thực hiện. NẾU A * là những gì họ sử dụng, vậy thì làm thế nào một thứ như thế được thực hiện trong môi trường 3D? Và làm thế nào chính xác làm các spline làm việc cho các góc tròn?


2
Tôi nghĩ rằng câu hỏi này quá mở đã kết thúc cho định dạng Hỏi & Đáp của SE. FAQ
John McDonald

1
Các trò chơi bạn đã đề cập phải chia bản đồ thành các nút cho A * bằng cách này hay cách khác. Quá trình phá vỡ đó không phải liên quan đến lưới hình vuông và có nhiều cách để làm điều đó. Hãy xem vid youtube.com/watch?v=nGC_kBCoHYc này , một trò chơi hay khiến người chơi không thể biết họ là ai thực sự làm đằng sau hậu trường.
XiaoChuan Yu

1
Có rất nhiều câu hỏi ở đây, vì vậy tôi thực sự không thể viết câu trả lời, nhưng tôi sẽ lưu ý rằng Dijkstra không trả về một đường dẫn và hầu hết các thuật toán tìm đường đều đa năng. Bạn chuyển đổi thế giới của mình, 2D hoặc 3D, thành một biểu đồ được kết nối và chạy thuật toán tìm đường trên đó.
Gregory Avery-Weir

Chỉ để tham khảo: Tôi đã trả lời câu hỏi tại Stack Overflow .
Julian

1
Cho phép tôi nói. Câu hỏi này nhận được 4 lượt ủng hộ trên SO, so với 4 phiếu bầu gần đây trên GDSE. Tôi không thể không cảm thấy rằng người điều hành trên trang web này đang quá tích cực. Chắc chắn, tôi có thể thấy câu hỏi đi ngược lại các nguyên tắc được chỉ định trong Câu hỏi thường gặp như thế nào, nhưng trích dẫn, những hướng dẫn đó được đưa ra để ngăn chặn diminishing the usefulness of our site. Câu hỏi này đã được yêu thích 3 lần rồi, đó là bằng chứng cho thấy nó hữu ích với một số người dùng. Vì vậy, tôi không thể không cảm thấy rằng bỏ phiếu để đóng nó và có nguy cơ loại bỏ cuối cùng, sẽ phản tác dụng hơn rất nhiều.
David Gouveia

Câu trả lời:


62

Quá nhiều câu hỏi cùng một lúc, vì vậy thật khó để đưa ra một câu trả lời cụ thể nhưng để thảo luận về một vài trong số các chủ đề này. Tôi sẽ chia câu trả lời thành hai và cố gắng giải quyết nó tốt nhất có thể. Tôi không yêu cầu bất kỳ danh sách nào trong số này là đầy đủ , nhưng chúng là một trong những phương pháp khác nhau mà tôi có thể nhớ.


Phần 1 - Thuật toán tìm đường

Đối với người mới bắt đầu, có nhiều cách để thực hiện tìm đường, nhưng không phải tất cả đều trả về đường đi ngắn nhất, hoặc hiệu quả hoặc thậm chí đáng tin cậy. Ví dụ:

  • Các phương pháp nguyên thủy không "nhìn về phía trước" và thực hiện từng bước một:

    • Bước lùi ngẫu nhiên - Thực hiện từng bước một theo hướng mục tiêu. Nếu gặp chướng ngại vật, hãy cố gắng khắc phục xung quanh nó bằng cách lùi lại một chút theo hướng ngẫu nhiên và sau đó thử lại. Không đáng tin cậy chút nào và sẽ bị mắc kẹt trong vô số tình huống.

    • Truy tìm chướng ngại vật - Cách tiếp cận khác, tương tự như bước lùi ngẫu nhiên nhưng thay vì quay lại ngẫu nhiên, bắt đầu lần theo dấu vết xung quanh đối tượng một khi va chạm được tìm thấy, như thể bạn có bàn tay phải bị kẹt vào tường và phải di chuyển chạm vào nó. Một khi không có va chạm tiếp tục di chuyển theo hướng của mục tiêu. Một lần nữa có thể bị mắc kẹt trong nhiều tình huống.

  • Các phương thức nhìn về phía trước để tìm toàn bộ đường dẫn cùng một lúc:

    • Breadth First Search - Chuyển đồ thị đơn giản bằng cách truy cập từng lớp trẻ em tại một thời điểm, dừng lại khi tìm thấy đường dẫn. Nếu đồ thị không có trọng số (tức là khoảng cách giữa mỗi nút liền kề luôn giống nhau), nó tìm thấy đường đi ngắn nhất mặc dù không quá hiệu quả. Đối với các biểu đồ có trọng số, nó có thể không trả về đường đi ngắn nhất, nhưng sẽ luôn tìm thấy một biểu đồ nếu nó tồn tại.

    • Độ sâu tìm kiếm đầu tiên - Một cách khác để duyệt qua biểu đồ, nhưng thay vì lấy từng lớp một, thuật toán sẽ cố gắng tìm kiếm sâu vào biểu đồ trước. Phương pháp này có thể có vấn đề nếu độ sâu của tìm kiếm không bị giới hạn, đặc biệt là khi sử dụng triển khai đệ quy, điều này có thể dẫn đến tràn ngăn xếp, do đó, sẽ an toàn hơn khi thực hiện lặp lại bằng cách sử dụng ngăn xếp.

    • Tìm kiếm đầu tiên tốt nhất - Tương tự như Tìm kiếm đầu tiên của Breadth nhưng sử dụng phương pháp phỏng đoán chọn người hàng xóm hứa hẹn nhất trước tiên. Con đường được trả về có thể không phải là ngắn nhất, nhưng nó chạy nhanh hơn so với tìm kiếm đầu tiên. A * là một loại Tìm kiếm đầu tiên tốt nhất.

    • Phương pháp của Dijkstra - Theo dõi tổng chi phí từ đầu đến mọi nút được truy cập và sử dụng nó để xác định thứ tự tốt nhất để duyệt qua biểu đồ. Hoạt động với các biểu đồ có trọng số và trả về đường dẫn ngắn nhất, nhưng có thể cần nhiều tìm kiếm.

    • A * - Tương tự Dijkstra nhưng cũng sử dụng phương pháp phỏng đoán để ước tính khả năng mỗi nút gần với mục tiêu, để đưa ra quyết định tốt nhất. Do heuristic này, A * tìm ra con đường ngắn nhất trong đồ thị có trọng số một cách kịp thời hơn nhiều.

  • Sau đó, có các biến thể của A * (hoặc tối ưu hóa tìm đường nói chung) làm cho nó nhanh hơn hoặc thích nghi hơn với các giai đoạn nhất định, chẳng hạn như (xem câu trả lời liên quandanh sách toàn diện trên cstheory.SE ):

    • LPA * - Tương tự A * nhưng có thể nhanh chóng tính toán lại đường dẫn tốt nhất khi thực hiện một thay đổi nhỏ cho biểu đồ
    • D * Lite - Dựa trên LPA *, nó cũng làm điều tương tự, nhưng giả sử "điểm bắt đầu" là một đơn vị di chuyển về phía kết thúc trong khi thay đổi biểu đồ đang được thực hiện
    • HPA * (Phân cấp) - Sử dụng một số lớp ở các mức độ trừu tượng khác nhau để tăng tốc tìm kiếm. Ví dụ, một lớp cấp cao hơn có thể chỉ đơn giản là kết nối các phòng, trong khi một lớp cấp thấp hơn sẽ tránh được các chướng ngại vật.
    • IDA * (Lặp đi lặp lại sâu) - Giảm mức sử dụng bộ nhớ so với A * thông thường bằng cách sử dụng độ sâu lặp lại.
    • SMA * (Đơn giản hóa giới hạn bộ nhớ) - Chỉ sử dụng bộ nhớ khả dụng để thực hiện tìm kiếm.
    • Jump Point Search - Tín dụng cho Eric trong các bình luận để đề cập đến nó! Tăng tốc độ tìm đường trên bản đồ lưới chi phí thống nhất ( liên kết ).

Phần 2 - Đại diện không gian tìm kiếm

Và cuối cùng để giải quyết câu hỏi này:

Tôi biết A * giống như thuật toán sử dụng trong các trò chơi 2D. Điều đó thật tuyệt vời và tất cả, nhưng còn những game 2D không dựa trên lưới thì sao?

Hai quan niệm sai lầm lớn ở đây! Trong thực tế:

  1. A * không quan tâm nếu trò chơi là 2D hoặc 3D và phù hợp như nhau cho cả hai trường hợp.
  2. A * hoạt động dưới bất kỳ biểu diễn đồ thị nào , vì vậy nó không quan tâm liệu thế giới có phải là lưới hay không.

Vì vậy, nếu thế giới không cần phải là một lưới, bạn có thể đại diện cho nó theo những cách nào khác? Dưới đây là tổng quan ngắn gọn về các cách phân vùng không gian thế giới cho tìm đường và hầu hết các cách này đều hoạt động cho cả 2D và 3D:

  • Lưới hình chữ nhật - Thế giới phân vùng thành lưới hình vuông thông thường với mỗi ô trong lưới là một nút trong biểu đồ và kết nối giữa hai nút không bị cản trở là một cạnh.

    nhập mô tả hình ảnh ở đây

  • Quadtree - Một cách khác để phân vùng không gian, nhưng thay vì phân vùng thành một lưới các ô có kích thước thông thường, phân vùng thành bốn, sau đó phân chia đệ quy từng cái lại thành bốn. Thêm một chiều thứ ba làm cho nó một octree .

    nhập mô tả hình ảnh ở đây

  • Đa giác lồi - Phân vùng vùng có thể đi bộ thành một lưới các đa giác lồi liên kết với nhau. Mỗi đa giác trở thành một nút và các cạnh được chia sẻ là các cạnh của biểu đồ. Đây có thể là các hình tam giác, và đôi khi thậm chí là một lưới được tạo bởi một nghệ sĩ khi tạo các tài sản cấp. Thường được gọi là một lưới điều hướng . Xem liên kết này . Đây là một bộ công cụ xây dựng lưới điều hướng rất phổ biến: Recast .

    nhập mô tả hình ảnh ở đây

  • Điểm hiển thị - Cách phổ biến nhất là đặt một nút ngay bên ngoài mỗi đỉnh lồi của chướng ngại vật, sau đó kết nối từng cặp nút có thể nhìn thấy nhau. Kiểm tra liên kết này . Các nút không phải là các đỉnh mặc dù và có thể được nhà thiết kế đặt thủ công trong bản đồ. Trong trường hợp đó, hệ thống thường được gọi là biểu đồ điểm .

    nhập mô tả hình ảnh ở đây


1
Hai liên kết: 1) Mikko Mononen đã thực hiện công việc tìm đường Killzone 3 và anh ta có một blog rất hay, nơi anh ta ghi lại quá trình phát triển của Recast (trình tạo navmesh) và Detour (bộ công cụ tìm đường), cả theo giấy phép MIT và được sử dụng chẳng hạn trong Vương quốc Amalur: Tính toán . 2) Tìm kiếm điểm nhảy là, một trong những phát triển gần đây nhất trong tìm kiếm đường dẫn dựa trên lưới.
Eric
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.