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;2. map 管理器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_);
}};
map 管理器記錄所有地圖資訊,記錄某個座標其相鄰座標資訊,記錄某個座標是否可通行資訊、地圖的寬、高等、兩點的距離等。map管理器中維護乙個二維陣列
map_mgr_t(uint32_t width_, uint32_t height_):3. 獲取鄰居節點方法如下,限制不能斜著走,不同的遊戲可能有不同的實現m_map_nodes(null),
m_width(width_),
m_height(height_)
}}
void get_neighbors(uint32_t pos_, vector& ret_)4. 啟發式函式由於不能斜著走,那麼啟發式函式h 只是獲得x、y上偏移和。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())
}
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 ...