A*是一种搜索算法,一般基于一个估价函数f(x) = g(x) + h(x),通过这个函数来进行有方向的搜索以提高搜索的效率(而不是bfs、dfs那样的盲目搜索)
其中g(x)指从初始状态到当前状态的花费,h(x)为当前状态到终状态的花费的估计值,以两者之和来估计起始状态到终状态的总花费f(x)
在A*算法中,通过优先搜索最符合要求的f(x)表示的状态以提升搜索效率
其中g(x)指从初始状态到当前状态的花费,h(x)为当前状态到终状态的花费的估计值,以两者之和来估计起始状态到终状态的总花费f(x)
在A*算法中,通过优先搜索最符合要求的f(x)表示的状态以提升搜索效率
在求第k短路的问题中,g(x)指的是由起点到达当前点的路径长度,h(x)指当前点到达终点的最短路
而此时我们需要优先对估价函数值较小的状态进行搜索
故而可以使用优先队列对数据进行处理
而此时我们需要优先对估价函数值较小的状态进行搜索
故而可以使用优先队列对数据进行处理
一般对h(x)提前进行预处理,使用Dijkstra/SPFA预先求好最短路
由于A*总能够优先搜索 当前所有队列中结点距离终状态最近的结点,所以每次搜索到终点时都是当前最近的路
所以当第k次搜索到终点时的路径长度就是k短路的长度了
由于A*总能够优先搜索 当前所有队列中结点距离终状态最近的结点,所以每次搜索到终点时都是当前最近的路
所以当第k次搜索到终点时的路径长度就是k短路的长度了
A*核心代码:
int cnt; int Astar(){ if(st == en) k++; if(dis[st] == inf) return -1; priority_queue<ptr> q; ptr cur{st, dis[st], 0}; q.push(cur); while(!q.empty()){ ptr t = q.top(); q.pop(); int nt = t.now; if(nt == en) cnt++; if(cnt == k) return t.g; for(int i = 0; i < edges[nt].size(); i++){ int path = t.g + edges[nt][i].w; int now = edges[nt][i].to; q.push(ptr{now, path + dis[now], path}); } } return -1; }
st、en为起点、终点, dis数组为预处理的最短路
ptr结构体的定义:
struct ptr{ int now, F, g; // 当前点编号, 估价函数F, 当前路径g bool operator <(const ptr& a) const { if(this->F == a.F) return this->g > a.g; return this->F > a.F; } };