A *アルゴリズム研究ノート

A *アルゴリズムの基本原理

A-starアルゴリズムは、静的道路ネットワークの最短パスを解決するための最も効果的な直接検索方法であり、多くの検索問題を解決するための効果的なアルゴリズムでもあります。アルゴリズムの推定距離値が実際の値に近いほど、最終的な検索速度は速くなります。

F [i] = G [i] + H [i];

これは、A *アルゴリズムのコア式です。つまり、現在のコスト+将来の見積もりが最小の状態が毎回取り出されます推定値H [i] <=実際の将来のコスト

推定値が実際の将来のコストよりも大きい場合、A *アルゴリズムの正確性は保証されません。(「アルゴリズム競争の上級ガイド」の反例を読みましたが、理解できませんでした。理解できたら後で追加します)。

K短絡

#include<bits/stdc++.h>
using namespace std;
#define fp(i,a,b) for(register int i=a;i<=b;i++)
#define fb(i,a,b) for(register int i=a;i>=b;i--)
#define sc(a) scanf("%d",&a)
#define scf(a,b) scanf("%d%d",&a,&b)
const int MAXN=1e5+5;
struct Node{
	int f,g,h;
	bool operator<(const Node &a)const{
	    if(a.f==f) return a.g<g;
	    return a.f<f;
	}
};
struct Edge{
	int to,w,prev;
}edge1[MAXN<<1],edge2[MAXN<<1];
int n,m,s,t,k,cnt1,cnt2,ans,head1[MAXN],head2[MAXN],dis[MAXN],vis[MAXN];
inline void add(int x,int y,int w){
	edge1[++cnt1].to=y;
	edge1[cnt1].w=w;
	edge1[cnt1].prev=head1[x];
	head1[x]=cnt1;
	edge2[++cnt2].to=x;
	edge2[cnt2].w=w;
	edge2[cnt2].prev=head2[y];
	head2[y]=cnt2;
}
inline void spfa(int st){
	queue<int> q;
	memset(dis,0x3f3f3f3f,sizeof(dis));
	q.push(st);vis[st]=1;dis[st]=0;
	while(!q.empty()){
		int x=q.front();q.pop();vis[x]=0;
		for(int i=head2[x];i;i=edge2[i].prev){
			int to=edge2[i].to;
			if(dis[to]>dis[x]+edge2[i].w){
				dis[to]=dis[x]+edge2[i].w;
				if(!vis[to]){
					vis[to]=1;
					q.push(to);
				}
			}
		}
	}
}
inline int Astar(int st,int ed){
	priority_queue<Node> q;
	if(st==ed) k++;
	if(dis[st]==0x3f3f3f3f) return -1;
	struct Node t,tt;
	t.g=0;t.h=st;t.f=t.g+dis[t.h];
	q.push(t);
	while(!q.empty()){
		tt=q.top();q.pop();
		if(tt.h==ed){
			ans++;
			if(ans==k) return tt.g;
		}
		for(int i=head1[tt.h];i;i=edge1[i].prev){
			int to=edge1[i].to;
			t.g=tt.g+edge1[i].w;
			t.h=to;
			t.f=t.g+dis[to];
			q.push(t);
		}
	}
	return -1;
}
int main(){
	scf(n,m);
	fp(i,1,m){
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
	}
	scanf("%d%d%d",&s,&t,&k);
	spfa(t);
	printf("%d\n",Astar(s,t));
	return 0;
}
/*
4 5
1 2 2
2 3 3
1 3 5
2 4 1
4 3 3
1 3 3
*/

A-starアルゴリズムの最も重要な部分は、適切な評価関数を見つけることです。この古典的なAスターテンプレート問題の評価関数は、終点から各点までの最短パスです。したがって、マップを一度反転して、最短パスを再度実行する必要があります。エンドポイントがk回だけ表示される必要がある場合、その現在のコストはk番目の短絡です。なぜなら、優先キューから取り出された要素は、現在の状況では常に最適なソリューションだからです。この質問はまた、開始点と終了点の一致を判断する必要があります。

おすすめ

転載: blog.csdn.net/weixin_43916777/article/details/104224307