要先了解A*算法,得首先了解BFS——广度优先遍历
广度优先搜索(BFS)基本概念
算法基础:BFS和DFS的直观解释
了解BFS之后,我们发现BFS不是很智能,BFS需要去遍历当前节点所有旁边的点,它是没有目标性的,像洪水一样,移动方向是四面八方。
我们想要把它变得更智能一点,也就是有目的性的去找终点。
这里就有一个启发函数
F = G + H
假设现在是从起点A到终点B
有了这个启发函数,那么就会让我们的寻路算法更加智能,因为它有了一个目标,往这个最终目标移动就行了。
具体可以看看这篇文章:A星(A*, A Star)算法详解.
这个是视频A*寻路算法详解 #A星 #启发式搜索
#include
#include
#include
using namespace std;
typedef pair<int, int> pii;//(横坐标,纵坐标)
typedef pair<int, pii> piii;//(当前点的F值,pii)
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};//四个方向
const int N = 1e3 + 10;
int g[N][N];//地图
map<pii, int> g_costs;//当前点到起点的G值
map<pii, pii> parent;//记录当前节点的父节点,用于找到最终路径
//H值,我这里计算的是曼哈顿距离
int Get_H(int cur_x, int cur_y, int ed_x, int ed_y){
return abs(ed_y - cur_y) + abs(ed_x - cur_x);
}
string Get_Path(pii st_point, pii ed_point){
string path = "";
pii cur_point = ed_point;
while(cur_point != st_point){
path += "(" + to_string(cur_point.first) + "," + to_string(cur_point.second) + ") <- ";
cur_point = parent[cur_point];
}
path += "(" + to_string(cur_point.first) + "," + to_string(cur_point.second) + ")";
return path;
}
int A_Star(int st_x, int st_y, int ed_x, int ed_y, int n, int m){
priority_queue<piii, vector<piii>, greater<piii>> heap;
heap.push({0, {st_x, st_y}});
while(heap.size()){
piii now = heap.top();
heap.pop();
pii point = now.second;
if(point.first == ed_x && point.second == ed_y) return now.first;
for(int i = 0; i < 4; i++){
int nx = point.first + dx[i], ny = point.second + dy[i];
int new_cost = g_costs[point] + 1;
pii ne_point = {nx, ny};
if(nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] == 0) continue;
if(parent.count(ne_point) == 0 || new_cost < g_costs[ne_point]){
g_costs[ne_point] = new_cost;
int f = new_cost + Get_H(nx, ny, ed_x, ed_y);
heap.push({f, ne_point});
parent[ne_point] = point;
}
}
}
return -1;
}
int main(){
int n, m;
int st_x, st_y, ed_x, ed_y;
cin >> n >> m;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> g[i][j];
}
}
cin >> st_x >> st_y >> ed_x >> ed_y;
cout << "起点: (" << st_x << "," << st_y << ")\n";
cout << "终点: (" << ed_x << "," << ed_y << ")\n";
cout << "距离为" << A_Star(st_x, st_y, ed_x, ed_y, n, m) << "步" << '\n';
cout << "具体路径为\n";
cout << Get_Path({st_x, st_y}, {ed_x, ed_y});
return 0;
}