再來填乙個坑。之前一直說要寫的a* 終於有空補上了,本篇部落格首先會介紹最基礎的a* 實現,在簡單a* 的基礎上,嘗試實現稍複雜的a* 演算法(帶有高度資訊的地形,允許對角線尋路等)。
本部落格不準備**a* 演算法的原理,這裡僅僅對a*演算法做乙個簡單介紹,對具體原理感興趣的同學請查閱相關資料。
a* 演算法是一種啟發式搜尋演算法。本質上來講,可以算作是廣度優先搜尋演算法的改進。我們知道,廣度優先搜尋總能找到路徑最短的最優解,因為它每次新的一輪遍歷永遠是離起始點最近的位置,這樣,當掃瞄到目標點時,可以保證目標點的距離是離起點距離最近的,也就是找到了尋路的最優解。
a* 演算法的執行過程與廣度優先搜尋類似,不同的是,a* 除了考慮當前點離起始點的距離外,還考慮了當前點離目標點的距離,我們分別用g和h來表示這兩個距離,由此我們有代價函式f = g+h。a*演算法每次查詢代價最低的點作為搜尋點,並更新搜尋節點列表。最終搜尋到目標位置。可以看到,a* 演算法得到的路徑並不一定最優。
對於每一次搜尋任務,我們維護兩個列表:openlist和closelist。 這兩個列表分別存放待訪問的節點和已訪問過的節點。對於每乙個迴圈,我們從openlist中取出f最小的點,並檢查它的四鄰域(上下左右四個點),若四鄰域的點中有已經處於openlist中的點,則做更新操作(如果該點新計算的f值比舊的f值更小),若有點處於closelist中,則不做任何操作,若不在以上列表,則計算他們的f值,並放入openlist。以此類推,直至到達最終點或openlist為空(不存在路徑)。
以下是用c++ 實現的a*尋路演算法,地圖上為1的點表示可達的點,-1則表示不可達。
#include
#include
#include
#include
const
int width = 100;
const
int height = 100;
using
namespace
std;
struct node
}; int calculateh(node* cur,node* end);
vector
find(node* start,node* end, unordered_map
>& mgraph);
void check(int x,int y,node* cur,unordered_map
>& openlist, unordered_map
>& endlist,node* end, unordered_map
>& mgraph);
node* findmin(unordered_map
>& openlist);
int main(int argc, char
const *argv)
}for(int i = 0;i<25;++i)
node * start = new node(0,0);
node * end = new node(10,10);
start->h = calculateh(start,end);
start->f = start->g+start->h;
auto ret = find(start,end,mgraph);
for(auto v:ret)
vector
find(node* start,node* end, unordered_map
>& mgraph) ;
if(mgraph[start->_x][start->_y]==-1||mgraph[end->_x][end->_y] == -1) ;
}unordered_map
> openlist;
unordered_map
> endlist;
openlist[start->_x][start->_y]=start;
vector
int,int>> dirs,,,};
bool isfind = false;
while(!isfind)
check(nx,ny,minnode,openlist,endlist,end,mgraph);
}if(isfind) break;
endlist[minnode->_x][minnode->_y] = minnode;
openlist[minnode->_x].erase(openlist[minnode->_x].find(minnode->_y));
}if(!isfind) return {};
vector
retvec;
auto tmp = end;
while(tmp)
reverse(retvec.begin(),retvec.end());
return retvec;
} void check(int x,int y,node* cur,unordered_map
>& openlist, unordered_map
> &endlist,node* end, unordered_map
>& mgraph)
if(mgraph[x][y]==-1) return;
if (endlist.find(x)!=endlist.end()&&endlist[x].find(y)!=endlist[x].end())
if(openlist.find(x)!=openlist.end()&&openlist[x].find(y)!=openlist[x].end())
}node * newnode = new node(x,y);
newnode->g = cur->g+1;
newnode->h = calculateh(newnode,end);
newnode->f = newnode->g+newnode->h;
openlist[x][y] = newnode;
newnode->parent = cur;
} int calculateh(node* cur,node* end)
node* findmin(unordered_map
>& openlist) }}
return n;
}
迷宮尋路(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...