A星路徑搜尋

2021-09-08 03:07:50 字數 3083 閱讀 5443

dijkstra 最短路徑演算法,大學資料結構教科書上都講過,這裡也不贅述了。但是為了及和一下幾個演算法做比較,我google 了乙個圖,非常直接的顯示dijkstra演算法的搜尋過程:

圖中以中心為起點,以輻射狀不斷向中心外搜尋(每次取距離起點最近的點),一圈一圈向外擴張,直到逼近目標點,完成路徑搜尋。

bsf 每次擴張節點,都選擇最接近目標的節點。dijkstra 是每次都選擇據起點最近的節點。區別是到起點的距離總是已知的,而都終點的距離只能是估計的。所以bsf 提供了啟發式函式h。常見的啟發式函式h有:

a 星演算法兼具dijkstra 準確和 bsf 的快速,在搜尋路徑時,通過啟發式函式h 計算當前節點到目標節點的距離,而起點到當前點距離已知,則每次選擇f = g + h 最小的節點。a星總是嘗試找到最短的路徑,阻礙物少的情況下效能接近bsf。

//! 新增到close 表

m_map.get_node(current.get_pos_index())->set_closed();

//! 找到當前節點的所有鄰居節點, 不同的遊戲中該函式實現可能不同

//! 有的遊戲可以走斜線,而有些不能,如坦克大戰就不能走斜線

m_map.get_neighbors(current.get_pos_index(), neighbors);

for (size_t i = 0; i < neighbors.size(); ++i)}//

! 如果該點既沒有在open,也沒有在close中,直接新增到open

else

if (false == neighbor_map_node->is_closed())

//! 如果已經在close 中,簡單跳過

else {} //

! closed ignore

}neighbors.clear();}//

! 找到了目標,逆序遍歷,得到完整的路徑

if (current.get_pos_index() == to_index)

path_.push_back(from_index);}//

! 最後將所有的已訪問過的節點狀態清楚, 為下次搜尋做準備

for (size_t i = 0; i < visited.size(); ++i)

visited.clear();

return

0;}open 表,維護待擴充套件的節點,每次從其中找到f = g + h 最小的節點,由pop_first 實現

open 表 是按照f = g + h 由大到小順排序的,是乙個multimap

typedef multimaptable_t;

struct open_table_t

int pop_first(search_node_t& ret)

void insert(const search_node_t& node_)

void update(uint32_t old_, const search_node_t& node_)

}this->insert(node_);

}};

2. map 管理器

map 管理器記錄所有地圖資訊,記錄某個座標其相鄰座標資訊,記錄某個座標是否可通行資訊、地圖的寬、高等、兩點的距離等。map管理器中維護乙個二維陣列

map_mgr_t(uint32_t width_, uint32_t height_):

m_map_nodes(null),

m_width(width_),

m_height(height_)

}}

3.  獲取鄰居節點方法如下,限制不能斜著走,不同的遊戲可能有不同的實現

void get_neighbors(uint32_t pos_, vector& ret_)

tmp = m_map_nodes + pos_ + 1;

if (tmp >= m_map_nodes && tmp < m_map_nodes + m_height * m_width && tmp->is_can_pass())

tmp = m_map_nodes + pos_ - m_width;

if (tmp >= m_map_nodes && tmp < m_map_nodes + m_height * m_width && tmp->is_can_pass())

tmp = m_map_nodes + pos_ + m_width;

if (tmp >= m_map_nodes && tmp < m_map_nodes + m_height * m_width && tmp->is_can_pass())

}

4. 啟發式函式由於不能斜著走,那麼啟發式函式h 只是獲得x、y上偏移和。

uint32_t heuristic(uint32_t from_, uint32_t to_)

astar_t 應該模板化, heuristic、distance、get_neighbors都應該是可定製的

效能引數測試,如1000*1000地圖上最壞情況的搜尋開銷

open表更新還可以優化,當更新g值後若小於迭代器前乙個節點,才需要執行刪除再插入

源**:

include 搜尋路徑

c中可以通過 include 和 include stidio.h 區別是 include 直接到系統指定目錄去查詢標頭檔案。include stidio.h 會先到當前目錄查詢標頭檔案,如果沒找到在到系統指定目錄查詢。gcc編譯時查詢標頭檔案,按照以下路徑順序查詢 1.gcc編譯時,可以設定 i選...

Fringe Search 路徑搜尋

尋路方法很多都把a 當成標準,它確實很不錯.fringe search邊緣搜尋比a 要好些,在記憶體使用和速度上都有改善.這是參照了 遊戲程式設計精粹7 中 超越a ida 和邊緣搜尋 fringe search beating a at pathfinding on game maps 和 fri...

gcc搜尋路徑

一 標頭檔案 搜尋會從 i開始 環境變數 c include path,cplus include path,objc include path 內定目錄 echo gcc wp,v x c fsyntax only 二 編譯時庫檔案 gcc會去找 l 再找gcc的環境變數library path ...