A* 算法
概念讲解
什么是 A*?
A* 是一种启发式搜索算法,使用估价函数引导搜索方向。
估价函数
- g(n):从起点到 n 的实际代价
- h(n):从 n 到终点的估计代价
正确性条件
h(n) 必须是可采纳的,即不高估实际代价。
实现
12345678910111213141516171819int aStar(int start, int end) {
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;
pq.push({h(start), start});
dist[start] = 0;
while (!pq.empty()) {
auto [f, u] = pq.top();
pq.pop();
if (u == end) return dist[u];
for (auto& [v, w] : graph[u]) {
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
pq.push({dist[v] + h(v), v});
}
}
}
return -1;
}考点分析
初赛考查方式
- 程序阅读: A* 算法
- 编程题: 启发式搜索
常见考点
- 估价函数设计
- A* 与 Dijkstra 关系
- 可采纳性
练习题
- A* 和 Dijkstra 的关系?
查看答案
A* 是 Dijkstra 的扩展:
- Dijkstra 只考虑 (实际代价)
- A* 同时考虑 和 (估计代价)
当 时,A* 退化为 Dijkstra。
- h(n) 的正确性条件?
查看答案
h(n) 必须是可采纳的,即:
其中 是从 n 到终点的实际最短距离。
也就是说,h(n) 不能高估实际代价。
- 什么时候 A* 退化为 Dijkstra?
查看答案
当 时,A* 退化为 Dijkstra。
此时 ,只考虑实际代价,不使用启发信息。
易错点
⚠️ 注意:
- h(n) 不能高估
- h(n)=0 时退化为 Dijkstra
- A* 通常比 Dijkstra 快
- 启发函数设计是关键