日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

A*搜索算法--游戏寻路

發(fā)布時間:2024/7/5 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 A*搜索算法--游戏寻路 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 1. 算法解析
    • 2. 總結

仙劍奇?zhèn)b傳這類MMRPG游戲中,有人物角色 自動尋路功能。當人物處于游戲地圖中某位置時,點擊另一個相對較遠的位置,人物就會自動地繞過障礙物走過去。這個功能是怎么實現(xiàn)的呢?

1. 算法解析

這是一個非常典型的搜索問題。起點是當下位置,終點是鼠標點擊位置。找一條路徑。路徑要繞過地圖中所有障礙,并且走的路不能太繞。最短路徑顯然是最聰明的走法,是最優(yōu)解。

但是如果圖非常大,那Dijkstra最短路徑算法的執(zhí)行耗時會很多。在真實的軟件開發(fā)中,面對的是超級大的地圖和海量的尋路請求,算法的執(zhí)行效率太低,是無法接受的。

一般情況下,我們都不需要非得求最優(yōu)解(最短路徑)。在權衡路線規(guī)劃質(zhì)量和執(zhí)行效率的情況下,只需要尋求一個次優(yōu)解就足夠了

  • A* 算法是對Dijkstra算法的優(yōu)化和改造。

Dijkstra 算法有點類似BFS算法,它每次找到跟起點最近的頂點,往外擴展。這種往外擴展有些盲目。舉一個例子。下圖對應一個真實地圖,每個點在地圖中的位置,用一個坐標(x,y)來表示,x橫坐標,y縱坐標。

在Dijkstra算法中,用一個優(yōu)先隊列,記錄已經(jīng)遍歷的頂點以及這個頂點與起點的路徑長度。頂點與起點路徑長度越小,優(yōu)先從優(yōu)先級隊列中取出來擴展,從圖中舉例可以看出,盡管找的是從s到t的路線,但是最先被搜索到的頂點依次是1,2,3。這個搜索方向明顯“跑偏"了。

之所以“跑偏”,是因為沒有考慮這個頂點到終點的距離,盡管1,2,3三個頂點離起始頂點最近,但離終點卻越來越遠。

如果綜合更多因素,把這個頂點到終點可能還要走多遠,考慮進去,綜合判斷哪個頂點先出隊列,是不是就可以避免“跑偏”呢?

當遍歷到某個頂點時,從起點走到這個頂點的路徑長度是確定的,我們記作g(i)。通過這個頂點跟終點之間的直線距離,也就是歐幾里得距離,來近似估計這個頂點跟終點的路徑長度。我們把這個距離記作h(i),專業(yè)叫法是啟發(fā)函數(shù)(heuristic function)。因為歐幾里得距離公式,會涉及比較耗時的開根號計算,所以一般計算曼哈頓距離(Manhattan distance)。曼哈頓距離是兩點之間橫縱坐標的距離之和。只涉及加減法、符號位反轉,所以更加高效。

int hManhattan(Vertex v1, Vertex v2) { // Vertex 表示頂點return Math.abs(v1.x - v2.x) + Math.abs(v1.y - v2.y); }

通過兩者之和 f(i)= g(i)+ h(i),來判斷哪個頂點最先出隊。能有效避免“跑偏"。這里f(i)的專業(yè)叫法是估價函數(shù)(evaluation function)。

A* 算法就是對Djkstra算法的簡單改造。在A*算法的代碼實現(xiàn)中,頂點Vertex類的定義,多了x,y坐標,f(i)值。

A* 算法跟Djkstra 算法主要有3點區(qū)別:

  • 優(yōu)先級隊列構建的方式不同。A*算法是根據(jù) f 值 f(i)=g(i)+h(i)來構建優(yōu)先級隊列,而Dijkstra 算法是根據(jù)dist值 g(i)來構建優(yōu)先級隊列;
  • A*算法在更新頂點dist值的時候,同步更新 f 值;
  • 循環(huán)結束的條件不一樣。Dijkstra 算法是在終點出隊列的時候才結束,A*算法是一旦遍歷到終點就結束。

盡管A* 算法可以快速找到從起點到終點的路線,但是它并不能像Dijkstra算法那樣,找到最短路線

Dijkstra 算法在回溯基礎上,利用動態(tài)規(guī)劃思想,對回溯進行剪枝,只保留起點到某個頂點的最短路徑,繼續(xù)往外擴展搜索。動態(tài)規(guī)劃相較于回溯搜索,只是換了一個實現(xiàn)思路,但它實際上也考察到了所有從起點到終點的路線,所以能得到最優(yōu)解。

A* 算法之所以不能像Dijkstra 算法那樣,找到最短路徑,主要原因是兩者的while 循環(huán)結束條件不一樣。

  • Dijkstra 算法是在終點出隊列的時候才結束
  • A*算法是一旦遍歷到終點就結束。

對于Dijkstra 算法來說,當終點出隊列的時候,終點的 dist 值是優(yōu)先級隊列中所有頂點的最小值,即便再運行下去,終點的dist值也不會再被更新了。
對于A* 算法來說,一旦遍歷到終點,我們就結束 while循環(huán),這個時候,終點的dist值未必是最小值。

A* 算法利用貪心算法的思路,每次都找 f 值最小的頂點出隊列,一旦搜到終點就不繼續(xù)考察其他頂點和路線。所以,它沒有考察所有路線,也就不能找出最短路徑。

如何借助A* 算法解決游戲?qū)ぢ?#xff1f;

游戲地圖并不像現(xiàn)實生活中那樣,存在規(guī)劃非常清晰的道路,更多的是寬闊的荒野、草坪等。換一種抽象的思路,把地圖分割成一個一個的小方塊。在某個方塊上的人物,只能往上下左右四個方向移動。把每個方塊看作一個頂點。方塊相鄰,它們之間連兩條有向邊,權值都是1。套用A* 算法。

2. 總結

A* 算法屬于一種啟發(fā)式搜索算法(Heuristically Search Algorithm)。啟發(fā)式搜索算法還有很多其他算法,比如 IDA* 算法、蟻群算法、遺傳算法、模擬退火算法等。

  • 啟發(fā)式搜索算法利用估價函數(shù),避免“跑偏”,貪心地朝著最有可能到達終點的方向前進。
  • 算法找出的路線,并不是最短路線。
  • 實際軟件開發(fā)中的路線規(guī)劃問題,并不需要非得找最短路線。鑒于啟發(fā)式搜索算法能很好地平衡路線質(zhì)量和執(zhí)行效率,它應用更加廣泛。

總結

以上是生活随笔為你收集整理的A*搜索算法--游戏寻路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。