簡體   English   中英

為什么A *路徑發現有時是直線,有時是對角線? (JAVA)

[英]Why does A* path finding sometimes go in straight lines and sometimes diagonals? (Java)

我正在開發一個簡單的基於2d網格的SIM游戲,並且具有完整的功能路徑查找功能。

我使用上一個問題中找到的答案作為實現A *路徑查找的基礎。 尋路2D Java游戲? )。

為了向您展示我真正想要的東西,我需要向您展示我制作的這個視頻截屏。 我只是在測試,看看這個人將如何移動到某個位置並再次返回,這就是結果......

http://www.screenjelly.com/watch/Bd7d7pObyFo

不同的路徑選擇取決於方向,意外的結果。 有任何想法嗎?

如果您正在尋找一個簡單的解決方案,我可以建議一些隨機化嗎?

我的意思是:在cokeandcode代碼示例中,有嵌套for循環生成“后繼狀態”(使用AI術語)。 我指的是它圍繞“當前”狀態在3x3方塊上循環的點,在堆上添加新的位置以供考慮。

一個相對簡單的修復方法(應該:)是一些代碼的隔離,並且在處理步驟的其余部分之前生成一個節點的鏈接列表。 然后是Containers.Shuffle(或者是Generics.Shuffle?)鏈接列表,並繼續處理那里。 基本上,有一個例程說,“createNaiveNeighbors(node)”返回LinkedList = {(node.x-1,node.y),(node.x,node.y-1)...}(請原諒pidgin Java,我正在嘗試(並且總是失敗)簡短。

但是,一旦構建鏈接列表,您應該能夠執行“for(節點n:myNewLinkedList)”而不是

for (int x=-1;x<2;x++) {

    for (int y=-1;y<2;y++) {

並且仍然使用完全相同的身體代碼!

理想情況下,這樣做會“改變”所考慮節點的順序,並創建更接近對角線的路徑,但無需更改啟發式。 路徑仍然是最有效的,但通常更接近對角線。

當然,缺點是如果你多次從A到B,可能會采取不同的路徑。 如果這是不可接受的,您可能需要考慮更嚴格的修改。

希望這可以幫助! -Agor

兩條路徑長度相同,因此算法正常工作 - 它找到了最短的路徑。 但是,A *算法沒有指定它將采用的最短路徑。 實現通常采用“第一”最短路徑。 沒有看到你的,不可能確切地知道原因,但是如果你想要每次都必須添加某種優先級規則時想要相同的結果(這樣你在搜索中首先出現了你想要的路徑)。

原因是您希望算法走的路徑。
我不知道您的A *使用的啟發式,但在第一種情況下,它必須首先到達隧道的末端,然后計划從隧道的末端到目標的方式。

在第二種情況下,對目標的最簡單的移動是直到它撞到牆壁然后它計划從牆壁到目標的方式。

大多數A *我知道在一個塊世界的情況下使用視線啟發式或曼哈頓距離 這種啟發式方法可以為您提供最短的路徑,但是如果障礙物出現的方式與視線不同,那么方式取決於您的出發點。
該算法將盡可能長時間地走在視線范圍內。

其實的原因很簡單:路徑總是嘗試使用最低的啟發式,因為它以貪婪的方式搜索。 更接近目標是一條最佳路徑。

如果允許對角線移動,則不會發生這種情況。

最可能的答案是,向南直行會使它最接近目標; 以相反的方式,這不是一個選擇,因此它分段優化子路徑,結果是交替向上/跨越移動被視為最佳。

如果您希望它沿着對角線返回,您將不得不在路徑上識別一些感興趣的點(例如隧道的口)並在您的啟發式中考慮這些點。 或者,您可以通過重新計算通過興趣點的任何子路徑,在算法中考慮它們。

回到過去,他們過去常常對地圖進行預先編譯的靜態分析,並在阻塞點放置尋路標記。 根據您的最終目標,這也可能是一個好主意。

如果你真的有興趣了解正在發生的事情,我建議你渲染一下A *搜索的步驟。 鑒於您的問題,它可能會讓您大開眼界。

在每種情況下,它都更喜歡更快接近目標節點的路徑,這就是A *的設計目標。

如果我看到了正確的話,球體在一條直線上首先向右移動,因為它不能直接朝向目標(路徑被阻擋)。 然后,它朝着目標直線前進。 它看起來只是對角線。

您的搜索首先在“向下”方向看? 這可以解釋算法。 嘗試改變它首先看起來'up'我打賭你會看到相反的行為。

根據您的astar的實現,您將看到與許多人提到的相同啟發式的不同結果。 這是因為關系,當兩個或多個路徑綁定您訂購開放集合的方式將決定最終路徑的外觀。 如果您有一個可接受的啟發式方法,您將始終獲得最佳路徑,但訪問的節點將隨着您擁有的關系數量而增加(相對於啟發式生成的關系不多)。

如果您不認為訪問更多節點是一個問題,我建議使用隨機化(這是您當前接受的答案)的建議。 如果您認為搜索更多節點是一個問題並想要優化,我建議使用某種類型的決勝局。 看來你正在使用曼哈頓距離,如果你使用歐幾里德距離當兩個節點作為決勝局並列時,你將獲得更直接的目標路徑,你將訪問更少的節點。 這是在沒有陷阱或目標視線的情況下。

為了避免在視線路徑中訪問具有阻擋元素的節點,我建議找到考慮這些阻塞元素的啟發式算法。 當然,新的啟發式方法不應該比正常的星形搜索做更多的工作。

我建議看看我的問題,因為它可能會產生一些想法和解決這個問題的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM