【轉】利用跳點搜索算法,優化A星尋路


在游戲中尋路是無處不在的。最著名的尋找最短路徑算法莫過與A*算法,實現方式有很多中,重要的是我們要掌握其原理。

在本教程中,我們將介紹一種相對較新的方法搜索——基於網格的世界的跳點的搜索,可以加速A*尋路算法。效率提升那是大大的。

我假設讀者已經明白A*算法的原理。如果你對A星尋路還不是很了解的話,我推薦你去看下這篇十分簡單明了的教程,了解A星算法原理,猛戳這里

好的,下面進入正題,開始講解Jump Point Search!(以下簡稱JPS)

先來看個Demo,做個對比實驗

 首先讓我們來看下老外用AS開發的一個Demo。Demo中黑色部分為不可行走區域,鼠標放到場景中任何個點,都會進行尋路算法,左上角的文本會提示尋路算法平均花費時間。

按【空格】鍵可以切換尋路算法模式為普通A*算法和JPS優化后的A*算法。

按【A】鍵可以添加NPC(貌似瓢蟲的動物)

按【R】鍵可以移除NPC

下面開始講解原理

常規A*算法,是向相鄰的格子中搜索可能的“最近節點”,然后把所有的“最近節點”連接起來,既為最終解。至於說怎樣的節點才是“最近節點”,本篇不做介紹,因為我前面已經設定了讀者是已經明白A*算法的原理的了。

問題的關鍵,就在於,我們一定要逐格逐格的去搜索嗎?隨着格子密集度提升,時間復雜度也將大幅提升。

那么我們如何去優化呢?

很簡單,對於大片的可行走區域,他們之間的任何一點都是可聯通的,我們可以省去這部分格子的“最近節點”搜索,這將是很大一部分的搜索的運算了。我們只需要找出一些相關的控制點,然后通過控制點之間的連通,省去大部分無謂的“尋找最近節點”的運算。

具體思路如下:

1 生成/擺放好 凸多邊形障礙物

2 “擴展”多邊形 擴展的大小取決於 尋路者的大小

3 將地圖中所有聯通點(以擴展后的多邊形為主)構成一張”圖”

4 將尋路者的起點和目標點作為”臨時節點”加入到3)中生成的圖里

5 在圖中尋路. 尋路后將之前的起點移除.

下面我們舉個例子:

1、有如下一張地圖,途中黑色填充為不可行走區
jsp2
2、 “擴展”多邊形 擴展的大小取決於 尋路者的大小,如圖中細線部

jsp2

3、將地圖中所有聯通點(以擴展后的多邊形為主)構成一張”圖”
jsp2

4 、將尋路者的起點和目標點作為”臨時節點”加入到3)中生成的圖里
jsp2

5、基於圖中的“控制點” ,在圖中尋路.

5.1、尋路第一步,將起始點作為搜索點,在與其相鄰的控制點中,找到可能的“最近節點”,如圖所示,最粗的兩條線的交點,就是我們要找的“最近節點”,因為其深綠色線段+淺綠色線段的長度之和,是最短的。這也是A*尋路的基本思路。
jsp2

5.2、尋路第二步,把上一步尋找到的“最近節點”,作為新的搜索點,然后重復同樣的判斷,找到新的新的“最近節點”,如圖所示,紅色的點,就是我們要找的新的“最近節點”
jsp2

5.3、尋路第N步,重復同樣的算法,尋找新的可能的“最近節點”,直到找到“終點”。如下圖,深綠色的路線,就是我們尋路結果。
jsp2

總結:

看到這里,我想大家一定都懂了,也肯定明白了,為什么利用JPS算法能夠大大提高A*尋路的效率。因為它省去了一些無謂的判斷節點。當然它是需要在尋路之前,開銷一些空間和時間去進行地圖的預處理。不過這點開銷,在后面尋路算法中又大大地賺了回來。

附錄:

在這里提供一個HTML5寫的Demo,需使用兼容HTML5的高富帥瀏覽器,方能運行,屌絲IE6請繞道。猛戳這里。可以更加清晰的體現Jump Point Search算法的輪廓。

我的微博:@我就叫向佳        

感謝@大城小胖

【轉自】http://www.36haojie.com/index.php/2013/08/jumppointsearch/

原文鏈接:http://gamedev.tutsplus.com/tutorials/implementation/speed-up-a-star-pathfinding-with-the-jump-point-search-algorithm/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM