尋路演算法 A (一)

2021-06-26 18:03:02 字數 2061 閱讀 7144

說到 a* 演算法相信都不陌生。做遊戲的人都多多少少的接觸過,而且網上教程也是一大堆。比如非常詳細的 我開始學習 a* 也是看的這個)。

以下是我個人對 a* 的理解。

首先要明白 a* 是基於地圖格仔(可以是方形,三角形,六邊形等)(每乙個格仔也是乙個節點)尋路的。a*  中最重要的一點是要明白 a* 是啟發式的。a* 的目的是要尋找從當前節點到目標節點的最短的路徑。 

a* 中重要的值  g,h, f 

g 值:從 startgrid 開始沿著尋找的路徑,移動到當前節點的移動耗費。每次計算現在的當前節點的 g 是通過它的父節點的 g 值加上這個節點本身自己的耗費。不同的節點耗費可能是不同的,比如 平地,山坡,沼澤,河流。通過他們的耗費肯定是不相同的。比如過河要坐船,遇到沼澤要繞行(否則.....)。

h 值:從指定節點到 goalgrid 的估計耗費。h 值的估算有很多方式,可以根據程式自己定義。也可以使用 曼哈頓方法。它計算從當前節點到目標及誒單之間的水平和垂直的節點的數量總和。比如現在的位置 curgrid 到 goalgrid 的 h 值的計算方式就是 h = abs(goalgrid.x - curgrid.x) + abs(goalgrid.y - curgrid.y); 

f = g + h; f 即當前位置到目標位置的估計的總的耗費。(這個值最重要,一般來說 f 值越小就越靠近 goalgrid)

open 列表:從 startgrid 開始記錄當前節點的周圍節點。

close 列表:記錄的是從 startgrid 開始到 goalgrid 的過程中每次迴圈產生的 open 列表中 f 值最小的節點,這個節點也要從 open 列表中移除。

明白了以上概念,剩下的就是演算法的主要部分了。

1、將 startgrid 加入到 open 列表中

2、在 do while 迴圈中重複一下工作(為什麼是 do while 迴圈?欲知詳情請聽下回分解)

a、尋找 open 列表中 f 值最小的節點,(要記得將這個節點從 open 列表中移除),將這個節點作為當前節點 curnode

b、把 curnode 加入到 close 列表中

c、對 curnode 相鄰的每乙個節點做如下處理 (這裡是乙個 for 迴圈,相鄰的節點一般不會只有乙個吧) 臨近節點(nearnode)

a、如果 nearnode 已經在 close 列表中,那麼繼續下乙個 continue;

b、如果 nearnode 不在 open 列表中,那麼將它新增進去,(這裡可以對 open 列表進行排序),並且將curnode 設為 nearnode 的父節點。然後記錄下 nearnode 的 g 和 h 值。(f = g + h)

c、如果 nearnode 已經在 open 列表中,如果新的 g 值低於nearnode 的 g 值。(更低的 g 值,意味著耗費越少,現在都是節約為主)。那麼將 nearnode 的父節點更改為 curnode。並且重新設定 nearnode 的 g 值。

d、停止

1、如果找到了 goalgrid 並且將 goalgrid 加入到 close 列表中。

2、open 列表已經為空了。還是沒有找到 goalgrid。(這個時候 goalgrid 通常是不可到達的。)這個時候路徑不存在。

3、如果找到了路徑接下來的工作當然就是要儲存路徑了。從 goalgrid 開始,沿著父節點乙個節點乙個節點的移動直到回到了 startgrid。這個就是我們程式要的路徑。

哈哈,你找到到我家的路徑沒有。還來不來吃飯。

當然就我們目前的這個演算法想想還有好多的問題。

1、儲存 open 列表的時候演算法不夠優秀,如果真的用乙個列表來儲存,那麼每次插入節點到 open 列表中的時候都要從頭遍歷 open 列表,挨個比較 f 值。直到找到乙個比要插入的節點大的才停止。最好的時候是只比較 1 次,可是最差的時候要和 open 列表中所有的元素做比較。如果 open 列表中元素非常的多,這裡開銷將非常大。那該怎麼辦呢,當然有優化的方法。

2、程式中還有找不到路徑的地方。在遊戲中如果我是要移動到的目標是乙個障礙物上面,那麼肯定是找不到路徑。角色一直站在那裡不動,什麼你不動是什麼意思。這個給玩家的體驗那是...」什麼遊戲啊,體驗這麼差,不玩了「。這個該怎麼辦呢。

這些問題都將在尋路演算法 a* (二)中得到解決。

迷宮尋路(A星尋路演算法)

題目 假設我們有乙個7 5大小的迷宮,如下圖所示,綠色格仔表示起點,紅色的格仔表示終點,中間的3個深灰色格仔表示障礙物。請找到一條從起點到終點最短的路徑。解題思路 需要引入兩個集合和乙個公式,如下 具體步驟 把起點放入openlist 檢查openlist中是否有值,如果沒有則無法到達終點,結束尋路...

A 尋路演算法

問題 由於遊戲中尋路出了個小問題 玩家尋路到乙個死角後在那邊不停的來回跑,就是無法越過障礙物,就研究了下a 尋路演算法以解決這個問題 研究了幾天,自己寫了個demo這裡給出總結 原理 a 演算法給出的是權值最優的路徑而不是最短路徑 權值有f g h來表示 啟發式函式如下 f p g p h p h值...

A 尋路演算法

a 演算法是靜態環境下求最短路徑的不二之選,由於是啟發式搜尋,比dijkstra 深搜廣搜要快的多啦。a 也算是我第一次接觸的移動機械人演算法,csdn上的科普文章也不少,但我作為乙個機械的小白,實現出來還是小有成就感滴。今天抽空和大家分享一下原始碼,開發環境win7 64 opengl vs201...