Heuristic A * algorithm to solve the shortest path problem

Posted by delassus on Sun, 30 Jan 2022 07:15:25 +0100

A * algorithm:

In the process of search, an evaluation function is used to evaluate the current point, find the best state and search until the target is found.
The evaluation function F(x)=G(x)+H(x), where G(x) is the actual cost and H(x) is the heuristic function, which is heuristic. And the heuristic function should meet: H(x) < = H*(x), H*(x) is the real value, which means that the requirement of the heuristic function must be less than or equal to the real value. The selection of the heuristic function determines the quality of the A * algorithm. When the heuristic value is completely equal to the real value, the optimal situation will be achieved at this time.

A * algorithm to solve the shortest path problem

A * algorithm is a heuristic algorithm, which optimizes Dijkstra algorithm on the shortest path problem,
Add heuristic function to improve the efficiency of search. The heuristic function used in the following code is to use the shortest distance between the point and the end point, and the method to calculate the shortest distance between the point and the end point is to use dijksta algorithm to run from the end point as the starting point. In fact, the heuristic function obtained by dijksta is the real value, that is to say, the search efficiency is the highest in this case, which returns to the linear structure.

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
typedef pair<int, PII> PIII;
const int N = 1010, M = 200010;

int n, m, S, T;
int h[N], rh[N], e[M], w[M], ne[M], idx;
int dist[N];
bool st[N];

//Adjacency table storage
void add(int h[],int a,int b,int c)
{
    e[idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx++;
}

//Calculate the shortest distance from the end point T to each point as the heuristic function
void dijkstra()
{
    priority_queue<PII,vector<PII>,greater<PII>> heap;
    heap.push({0,T});//Search from the end
    memset(dist, 0x3f, sizeof dist);
    dist[T] = 0;

    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();

        int ver = t.y;
        if(st[ver]) continue;
        st[ver] = true;

        for(int i=rh[ver];i!=-1;i=ne[i])
        {
            int j = e[i];
            if(dist[j]>dist[ver]+w[i])
            {
                dist[j] = dist[ver] + w[i];
                heap.push({dist[j],j});
            }
        }
    }
}

int astar()
{
    priority_queue<PIII, vector<PIII>, greater<PIII>> heap;//Small root pile
    // Whose d[u]+f[u] is smaller, who goes out of the queue first
    heap.push({dist[S], {0, S}});
    cout<<S;
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        int ver = t.y.y,distance = t.y.x;
        if(distance>0)
            cout<<"->"<<ver;
        if(ver==T){//I found it
            return distance;
        }
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j = e[i];
            // Stack according to the real value + estimated value = d[j]+f[j] = dist[S,t] + w[t][j] + dist[j,T]
            // True distance+w[i]
            heap.push({distance+w[i]+dist[j],{distance+w[i],j}});
        }
    }
}

int main()
{
    cin >> m >> n;
    memset(h,-1,sizeof h);
    memset(rh,-1,sizeof rh);
    for(int i=0;i<n;i++)
    {
        int a,b,c;
        cin >> a >> b >> c;
        add(h,a,b,c);
        add(rh,b,a,c);
    }
    cin >> S >> T;
   
    // The shortest distance from each point to the end point is used as the estimation function f[u]
    dijkstra();
    printf("\n from%d reach%d The shortest path length is:%d\n",S,T,astar());
    
    return 0;
}

Operation results:

Comparison between Dijkstra algorithm and A * algorithm

Dijkstra algorithm and A are commonly used algorithms for the shortest path problem. Let's compare the characteristics of these two algorithms.
1.Dijkstra algorithm calculates the shortest path length from the source point to all other points, and A the shortest path from the focus point to the point (including the specific path).
2.Dijkstra algorithm is based on more abstract graph theory. A algorithm can be more easily used in such as game map routing.
3. The essence of Dijkstra algorithm is breadth first search, which is A divergent search, so the spatial complexity and time complexity are relatively high. For the current point on the path, algorithm A not only records the cost to the source point, but also calculates the expected cost from the current point to the target point. It is A heuristic algorithm, A depth first algorithm (optimal evaluation function), or A combination of BFS+DFS (estimated value < real value).
4. From the first point, when there are many target points, A * algorithm will bring in A large amount of repeated data and complex evaluation functions. Therefore, Dijkstra algorithm will become A better choice if it is not required to obtain A specific path and need to compare the path length.

reference resources: https://blog.csdn.net/dujuancao11/article/details/109749219

Topics: data structure