Astar 搜索算法

Astar A* 算法路径搜索应用

在求解路径问题时,往往会搜索许多不必要的路径,计算机无法简单地实现人的宏观思维

所以,可以给当前需要搜索的路径增设一个估价函数,令计算机判断当前的最优解,这样可以节省许多不必要的时间开支

估价函数预处理出每个状态到目标状态的所需代价的估计值 \(f(x)\),实际值为 \(g(x)\),应当满足估计值不大于实际值 \(f(x)\le g(x)\) (越接近越准确),这样的带有估价函数的优先队列 BFS 叫做 Astar 算法


在 BFS 过程中,维护一个堆,每次取出堆中 当前代价+未来估价 的最小状态进行扩展

例如求解第 \(K\) 短路问题:给定 \(n\) 个节点与 \(m\) 条边的有向图,求从 \(s\)\(t\) 的第 \(K\) 短路

未来估价函数的计算

\(f_i\) 表示第 \(i\) 个节点到 \(t\) 的距离,这里可以通过 Dijkstra 算法,以 \(t\) 为起点 \(s\) 为终点跑一遍,最后可以计算出精确的 \(f_i=g_i\)

注意需要额外存一张反向图,这里以 rhe 表示

struct edge{
	long long v,w;
};
vector<edge> rhe[5010];

void dijkstra(void){
	priority_queue<pair<long long,long long>> q;
	memset(f,0x3f,sizeof f);
	f[t]=0;
	q.push({0,t});
	while (q.size()){
		auto t=q.top();
		q.pop();
		if (vis[t.second]) continue;
		vis[t.second]=1;
		for (auto iter:rhe[t.second]){
			if (f[iter.v]>f[t.second]+iter.w){
				f[iter.v]=f[t.second]+iter.w;
				q.push({-f[iter.v],iter.v});
			}
		}
	}
}

Astar的实现

正向跑一边优先队列的 BFS,堆中维护三元组 \(\{dis_{s,i}+f_i,i,d\}\),按照 \(dis_{s,i}+f_i\) 从小到大排序

分别表示: \(s\)\(i\) 的距离 + \(i\)\(t\) 的未来估价函数,\(i\) 点编号,\(d\) 记录的总路径长度

在过程中,我们只允许每个点最多入队 \(K\) 次,当 \(t\) 节点第 \(K\) 次出队时,对应三元组中的 \(d\) 就为所求的第 \(K\) 短路

long long astar(void){
	priority_queue<node> q;
	q.push({f[S],S,0});
	while (q.size()){
		auto t=q.top();
		q.pop();
		cnt[t.v]++;
		if (cnt[T]==K)//终点出队k次
			return t.d;
		for (auto iter:he[t.v])
			if (cnt[iter.v]<K)
				q.push({t.d+iter.w+f[iter.v],iter.v,t.d+iter.w});
	}
	return -1;
}

如果需要求严格的第 \(K\) 短路,即当路径长度不同时才算为不同的第 \(K\) 短路,需要增设一个变量记录上一次的答案

如果这一次得到路径长度与上一次相同,那么就需要令 \(K+1\)(当前的路径无效)

struct node{
	long long s,v,d;
	bool operator<(const node&x)const{
		return s>x.s;
	}//重载运算符,使优先队列按照s从小到大排列
};

long long mem=-1;

long long astar(void){
	priority_queue<node> q;
	q.push({f[s],s,0});
	while (q.size()){
		auto t=q.top();
		q.pop();
		
		if (t.v==K){
			if (mem==t.d) K++;
			else mem=t.d;
		}
		
		cnt[t.v]++;
		if (cnt[T]==K)
			return t.d
		for (auto iter:he[t.v])//he表示正向图
			if (cnt[iter.v]<K)
				q.push({t.d+iter.w+f[iter.v],iter.v,t.d+iter.w});
	}
	return -1;
}
posted @ 2025-03-01 19:04  才瓯  阅读(143)  评论(0)    收藏  举报