Nhận thức tình huống trong việc tìm đường


11

Giả sử bạn phải tìm con đường ngắn nhất xuyên qua ngục tối, nơi một số lối đi nhất định chỉ được mở cho bạn sau khi một số vật phẩm nhất định được thu thập, chẳng hạn như cửa bị khóa và chìa khóa.

Phản ứng ruột bình thường đối với các từ "con đường ngắn nhất" rõ ràng sẽ là A *. Nhưng A * sẽ thất bại trong một môi trường như vậy, vì tôi thấy nhiều vấn đề khi xác định một heuristic đáng tin cậy và, ngoài ra, rất có thể, một nút phải được truy cập nhiều lần, điều này cũng không thể xảy ra trong A * thông thường và cũng sẽ không thể làm cho heuristic khó hơn.

Những gì tôi nghĩ chỉ đơn giản là tìm kiếm một con đường từ đầu ngục tối đến cuối, bỏ qua bất kỳ cánh cửa bị chặn. Sau khi tìm thấy đường dẫn này, đối với mỗi cánh cửa chặn đường chúng ta, một con đường bổ sung tìm chìa khóa thích hợp và quay lại cánh cửa sẽ được tìm kiếm và đi qua trước khi cánh cửa thậm chí chạm tới. Hệ thống tương tự sẽ được sử dụng để xử lý một tình huống, trong đó đường dẫn đến chìa khóa cần thiết để mở một cánh cửa lại bị chặn bởi một cánh cửa khác, cần phải được mở trước.

Một vấn đề lớn mà tôi thấy với giải pháp của mình là sau khi tìm thấy tất cả các con đường bao gồm cả những con đường để mua vật phẩm, tổng quãng đường mà đại lý đi được có thể không phải là nhỏ nhất có thể, vì có thể có những cánh cửa bị chặn khác nằm xa mục tiêu hơn nhưng có chìa khóa thích hợp của họ dễ dàng hơn nhiều có sẵn. A * sẽ bỏ qua những cánh cửa này trên đường đèo đầu tiên, nơi những cánh cửa bị chặn đơn giản bị bỏ qua.

Tôi chắc chắn tôi không phải là người đầu tiên cố gắng giải quyết vấn đề này và tôi sẽ đánh giá cao một số ý kiến ​​đóng góp cho vấn đề này.


Tôi không biết A * được triển khai thường xuyên như thế nào, nhưng tôi đã thấy một triển khai có nhiều đường dẫn khác nhau có thang đo "trọng lượng", điều này sẽ thay đổi mức độ hấp dẫn của các đường dẫn khác nhau. Bạn không thể tính toán tất cả các đường dẫn có thể, và sau đó đặt "trọng lượng" của các đường dẫn đi qua một cánh cửa bị khóa thành vô cực? Điều này sẽ khiến con đường đó dường như dài vô tận, và do đó không bao giờ được sử dụng. Điều này là tất nhiên áp dụng nếu bạn tính toán trước các đường dẫn thay vì thực hiện nó cho mỗi thực thể mỗi bản cập nhật.
William Mariager

Cảm ơn bạn đã trả lời, nhưng điều bạn quên là việc mở khóa cửa có thể là cách duy nhất đến nút mục tiêu, trong trường hợp thuật toán bạn đề cập sẽ không tìm thấy đường dẫn. Hoặc, nếu trọng lượng của đường dẫn bị chặn đơn giản là vô hạn, nó sẽ chọn một trong những đường dẫn bị chặn và đứng trước vấn đề ban đầu của tôi.
Marc Müller

Câu trả lời:


8

Cách xử lý tình huống như vậy một cách tối ưu bằng cách sử dụng A * đơn giản là mở rộng không gian tìm kiếm. Đó là, hãy tưởng tượng rằng có tồn tại một bản sao của ngục tối riêng biệt cho mỗi tổ hợp vật phẩm mà nhân vật của bạn có thể mang theo.

Trong mỗi bản sao của ngục tối, các cửa có thể qua được chính xác là những cánh cửa có thể được chuyển qua bằng cách sử dụng bộ vật phẩm tương ứng. Cách duy nhất để chuyển từ bản sao ngục tối này sang bản sao khác là đứng trên vị trí của một vật phẩm và nhặt nó lên.

Bạn có thể mở rộng thủ thuật này để bao gồm các thay đổi trạng thái khác, chẳng hạn như các công tắc có thể mở và / hoặc đóng cửa. Bạn thậm chí có thể cho phép người chơi thả vật phẩm, mặc dù điều này có thể trở nên phức tạp do trạng thái phải bao gồm vị trí của từng vật phẩm bị rơi, làm tăng không gian tìm kiếm tiềm năng rất lớn.

Một tối ưu hóa rất hữu ích là tính toán trước các đường đi ngắn nhất từ ​​mỗi cửa (thực ra là mỗi bên của mỗi cửa) và chuyển đến từng cửa / vật phẩm có thể tiếp cận khác, giả sử rằng tất cả các cửa đều bị khóa . Khi bạn có các đường dẫn đó, bạn chỉ có thể coi mỗi đường đó là một cạnh có trọng số trong biểu đồ kết nối các vị trí quan trọng này với nhau và bỏ qua tất cả các vị trí khác.

Ví dụ, giả sử rằng ngục tối của bạn có mười cửa và năm chìa khóa. Sau đó, sẽ có 2 * 10 + 5 = 25 vị trí quan trọng và 2 ^ 5 = 32 kết hợp mục có thể, với tổng số 25 * 32 = 800 nút trong không gian tìm kiếm đầy đủ. Đây là một con số rất khiêm tốn, đặc biệt là phần lớn không gian tìm kiếm có khả năng không thể truy cập được.


5

Từ quan điểm trong thế giới thực: Nếu bạn đi từ A đến B và tìm thấy một cánh cửa D theo cách của bạn đã bị khóa, bạn sẽ nhận ra rằng bạn phải tìm khóa D. Vì vậy, nếu AI của bạn không biết như con người thông thường , điều đó sẽ liên quan đến việc tìm kiếm chìa khóa, đó là một tập hợp các bước tìm đường nhỏ trong chính nó. Mặt khác, bạn có thể muốn AI của mình biết, thậm chí trước khi thử một con đường, rằng có một cánh cửa bị khóa trên tuyến đường đó, và trong trường hợp đó có lẽ nó cũng sẽ biết tìm chìa khóa ở đâu.

Dù bằng cách nào, vấn đề là một trong những kết nối ở hai cấp độ. Ở cấp độ "trên mặt đất", bạn biết rằng bạn luôn có thể di chuyển an toàn trong một khu vực không phân chia ... không bị chia cắt bởi các cửa bị khóa, đó là. Đây là nơi bạn có thể sử dụng triển khai tìm đường dẫn A * hiện tại của mình một cách tự do. . chuyển động thực thể, nhưng nó giống như đi bộ với đôi mắt u ám, thay vì khảo sát khu vực xung quanh bạn trước - bạn có khả năng bước vào một cột đèn. Hoặc trong trường hợp này, một cánh cửa bị khóa. Vì vậy, các bản đồ cấp mặt đất mà A * của bạn chạy trên phải hạn chế người chơi chỉ di chuyển trong khu vực hiện tại.

Tiếp theo, có một bản đồ cấp cao hơn, đó là cấu trúc liên kết nhiều hơn so với địa hình trong tự nhiên. Nó không thực sự quan tâm đến các chi tiết trên mặt đất của chướng ngại vật và v.v., nó chỉ quan tâm đến sự kết nối giữa các khu vực. Bản đồ tô pô này có các kết nối giữa các vùng chẵn hiện có cửa bị khóa giữa chúng, vì nó cho thấy kết nối lý tưởng của tất cả các vùng trong ngục tối của bạn. Trong các cạnh của nó - mỗi cạnh đại diện cho một cánh cửa giữa các khu vực - nó lưu trữ khóa nào cần thiết, nếu có, để mở cánh cửa đó, nếu không, nó được coi là mở. Vì vậy, khi tìm kiếm biểu đồ này cho đường dẫn ngắn nhất, nên giới hạn đường dẫn tìm thấy chỉ các tuyến đã mở , bằng cách kiểm tra dữ liệu ở các cạnh khi tìm kiếm chạy. Kết nối ở đây không ngụ ý sự cởi mở, mà nó ngụ ý sự cởi mở tiềm năng.

Khi bạn muốn di chuyển đến một điểm nằm trong một khu vực riêng biệt, trước tiên bạn tìm kiếm bản đồ cấp cao hơn để tìm đường dẫn. (A * hoặc bất kỳ thuật toán đường dẫn ngắn nhất nào khác có thể được sử dụng ở cấp độ này.) Khi bạn tìm thấy một đường dẫn, bản đồ cấp cao hơn đó cũng sẽ cung cấp thông tin về cánh cửa nào bạn cần sử dụng để đi từ khu vực hiện tại của bạn đến khu vực khác. Bây giờ, trong khu vực địa phương, bạn có thể thực hiện AI trên mặt đất để điều hướng đến cánh cửa đó. Khi đã đạt được cánh cửa, nhân vật của bạn có thể đi qua cánh cửa / cổng thông tin đó. Anh ta hiện đang ở khu B. Nếu đây là khu vực mục tiêu, anh ta có thể sử dụng điều hướng trên mặt đất để đi đến chìa khóa. Nếu không, thì bạn cần lặp lại bước một cho đến khi bạn đến vùng mục tiêu.

Có khả năng một chìa khóa đang được tìm kiếm nằm phía sau cánh cửa bị khóa ... và chìa khóa của cánh cửa đó cũng tương tự ... và cứ thế tiếp tục quảng cáo. Đây thực chất là một vấn đề giải quyết phụ thuộc và có một vài cách để giải quyết vấn đề này, một trong số đó là Petri Nets. Xem này giấy tuyệt vời.

Tái bút Nếu bạn đang tạo dungeon của mình theo thủ tục, thì khi bạn làm như vậy, bạn có thể lưu trữ thông tin về thứ tự phụ thuộc, miễn là bạn đã biết vị trí bắt đầu của người chơi.


2

Phản ứng ruột bình thường đối với các từ "con đường ngắn nhất" rõ ràng sẽ là A *. Nhưng A * sẽ thất bại trong một môi trường như vậy, vì tôi thấy nhiều vấn đề khi xác định một heuristic đáng tin cậy và, ngoài ra, rất có thể, một nút phải được truy cập nhiều lần, điều này cũng không thể xảy ra trong A * thông thường và cũng sẽ không thể làm cho heuristic khó hơn.

Thứ nhất, một heuristic đáng ngưỡng mộ không cần phải hoàn hảo. Nó chỉ phải là một đánh giá thấp và nó phải tốt hơn không có gì. Cho rằng bạn đang làm việc với khoảng cách thực tế, có vẻ như A * ít nhất sẽ có ích, và ngay cả khi heuristic không cải thiện tìm kiếm nhiều, thì có lẽ vẫn tốt hơn tìm kiếm theo chiều rộng tiêu chuẩn hoặc tương tự.

Thứ hai, A * có thể truy cập một nút bao nhiêu lần tùy thích. Hãy nhớ rằng A * không phải là thuật toán tìm đường mà là thuật toán tìm kiếm. Nó tìm kiếm thông qua các tiểu bang. Trong các trò chơi, chúng tôi thường đánh đồng một trạng thái với một vị trí, bởi vì chúng tôi không quan tâm đến việc bạn đạt đến trạng thái đó như thế nào - chỉ là con đường ngắn để đi đến đó. Tuy nhiên, trong một vấn đề như thế này, trạng thái là sự kết hợp của vị trí cộng với bất kỳ trạng thái có liên quan nào khác, chẳng hạn như các phím được giữ.

Tuy nhiên, sự thật là những biến chứng này sẽ chuyển A * từ các lĩnh vực 'rất hiệu quả' sang 'sẽ thành công, nhưng có lẽ không phải trong thời gian tôi yêu cầu'. Thời gian bạn yêu cầu là gì? Trong thực tế, tại sao bạn cần phải làm điều này - bạn có thực sự cần con đường ngắn nhất, hoặc bất kỳ con đường hợp lý nào cũng đủ?

Những gì tôi nghĩ chỉ đơn giản là tìm kiếm một con đường từ đầu ngục tối đến cuối, bỏ qua bất kỳ cánh cửa bị chặn. Sau khi tìm thấy đường dẫn này, đối với mỗi cánh cửa chặn đường chúng ta, một con đường bổ sung tìm chìa khóa thích hợp và quay lại cánh cửa sẽ được tìm kiếm và đi qua trước khi cánh cửa thậm chí chạm tới.

Thật dễ dàng để chứng minh rằng một hệ thống như vậy sẽ là tối ưu. Bạn sẽ bắt đầu con đường bổ sung từ đâu? Nếu ngay từ đầu, thì bạn đã lãng phí thời gian để vạch ra con đường ban đầu đến cửa. Nếu từ cuối, sau đó đặt một phím gần điểm bắt đầu có nghĩa là đường dẫn đi qua bản đồ hai lần khi một lần sẽ đủ. Nếu bạn cố gắng tính toán các điểm hợp nhất tối ưu cho các đường dẫn đến và đi từ cửa ra vào và đường dẫn ban đầu, điều đó sẽ mang lại kết quả tối ưu nhưng sẽ tốn nhiều tài nguyên do số lượng hoán vị và khó tạo thành một heuristic để đơn giản hóa việc tìm kiếm. Nếu bạn thêm nhiều khóa vào vấn đề thì bạn có vấn đề Nhân viên bán hàng du lịch không dễ giải quyết hiệu quả.

Những gì tôi sẽ cố gắng, nếu có thể thư giãn tiêu chí 'con đường ngắn nhất', là đây:

  • Tạo một biểu đồ cấp cao chỉ chứa các vị trí quan trọng - vị trí quan trọng, vị trí cửa, vị trí trong khu vực khóa và lưu ý khoảng cách đường thẳng giữa chúng. Nếu bản đồ của bạn đã phân chia thành các phòng hoặc các vị trí riêng biệt khác, điều đó thật tuyệt.
  • Sử dụng A * để tìm đường dẫn qua biểu đồ này, từ đầu đến cuối. Khoảng cách heuristic bình thường của Cartesian phải đủ để giữ cho nó có thể quản lý được.
  • Bây giờ, với đường dẫn được đơn giản hóa giữa các điểm này, hãy sử dụng A * một lần nữa để vẽ đường dẫn mức thấp từ điểm này sang điểm khác.
  • Tham gia các đường dẫn cấp thấp này với nhau để tạo thành toàn bộ con đường của bạn.

Khi tôi đã làm việc đó, tôi sẽ xem xét một số tối ưu hóa nhỏ - ví dụ. cân các khu vực với các phím một cách nhẹ nhàng hơn để đường dẫn mức thấp sẽ có nhiều khả năng thực hiện các đường vòng nhỏ để thu thập các khóa.


0

với thông tin bạn cung cấp Tôi nghĩ bạn có thể sử dụng A * chỉ với một chút sửa đổi. trong thuật toán A * bình thường, bạn đánh dấu mọi nút khi bạn vượt qua chúng để đảm bảo bạn sẽ không bao giờ vượt qua nó nữa. Đó là phần chính xác gây ra vấn đề với các Mục. Thay đổi chính là ghi nhớ các mục của bạn là gì khi trước đó bạn đã chuyển từ một nút. đây là một mã sudo giải thích ý tôi là gì:

if (nodestoCheck.notempty())
    newNode = nodeToCheck.first;
    if (notpassed(newNode.pos, newNode.items))
        if (room(newNode).containItem)
            add NewNode + room(NewNode).items 
        else
            do normal A* algorithm for new Node

với thuật toán này, trước tiên bạn bắt đầu kiểm tra tất cả các nút không có mục nào. có khả năng cao là nhóm tìm kiếm đầu tiên của bạn bị chặn bởi một số cánh cửa. nhưng nó sẽ tìm thấy chìa khóa cho cánh cửa đó trước khi nó tìm kiếm tất cả các phòng. từ khóa đó, bạn bắt đầu một tìm kiếm mới có khóa cụ thể đó. lần này khi bạn tới cửa bạn có thể vượt qua nó. thói quen tương tự tiếp tục cho đến khi bạn tìm đường ra khỏi ngục tối. vấn đề duy nhất có thể là tiêu thụ bộ nhớ bất cứ khi nào có nhiều cửa và chìa khóa. mặc dù nó sẽ không phải là vấn đề đối với ít nhất 10 hoặc 15 phím.


0

Tại sao bạn không sử dụng A * bình thường và mô hình các cửa bị khóa là các khu vực không thể vượt qua; một khi bạn nhặt chìa khóa (đi trên ô phím?), điều đó sẽ thay đổi cánh cửa bị khóa cụ thể đó thành một khu vực có thể qua được.

Điều này có nghĩa là công cụ tìm đường dẫn của bạn sẽ đi theo con đường không cần chìa khóa ngắn nhất và nếu tìm thấy chìa khóa trên đường đi, nó sẽ kết hợp điều đó vào đường dẫn của nó nếu điều đó có ích.

Điều đó có vẻ khá hợp lý với tôi. Nó không hoàn hảo, nhưng đó là một giải pháp đơn giản cho vấn đề.

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.