Notas de estudio del algoritmo A *

Principio básico del algoritmo A *

El algoritmo A-star es el método de búsqueda directa más eficaz para resolver el camino más corto en una red de carreteras estáticas, y también es un algoritmo eficaz para resolver muchos problemas de búsqueda. Cuanto más cerca esté el valor de distancia estimado en el algoritmo del valor real, más rápida será la velocidad de búsqueda final.

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

Ésta es la expresión central del algoritmo A *, es decir, el costo actual + el estado con la estimación futura más pequeña se saca cada vez . El valor estimado H [i] <= costo futuro real .

Si el valor estimado es mayor que el costo futuro real, no se puede garantizar la exactitud del algoritmo A *. (Leí el contraejemplo de la "Guía avanzada para la competencia de algoritmos" y no lo entendí. Lo agregaré más adelante si lo entiendo).

K cortocircuito

#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
*/

La parte más importante del algoritmo A-star es encontrar una función de valoración adecuada. La función de valoración de este problema clásico de plantilla de estrella A es el camino más corto desde el punto final hasta cada punto. Por lo tanto, debe invertir el mapa una vez y ejecutar el camino más corto nuevamente. Si el punto final solo necesita aparecer k veces, entonces su costo actual es el k-ésimo cortocircuito. Porque cada vez los elementos sacados de la cola prioritaria son las soluciones óptimas en las condiciones actuales . Esta pregunta también debe juzgar la coincidencia del punto de partida y el punto final.

Supongo que te gusta

Origin blog.csdn.net/weixin_43916777/article/details/104224307
Recomendado
Clasificación