Post

A*

A*

What is A-star?

A-star is the algorithm solving the single source shortest path question, which combined the Dijkstra and Heuristic Search. That means the A* is Dijkstra with eyes!

How does it work?

We need three functions:

  • $dist$: the real distance between start and the current node;

  • $h$: the estimate distance between the current node and the end;

  • $f$: the total estimate distance between the start and the end;

To inmplement the Heuristic Search, we use the Manhattan Distance which is suitable for the 4-Neighbor Graph \(h(u) = |x_u - x_{\text{goal}}| + |y_u - y_{\text{goal}}|\)

or Euclidean Distance which is suitable for the 8-Neighbor Graph \(h(u) = \sqrt{(x_u - x_{\text{goal}})^2 + (y_u - y_{\text{goal}})^2}\).

Using Dijkstra, We need to use a min-heap based on the $f$ function for the priority queue.

Implement in c++ code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
vector<int> x, y; // using Manhattan Distance and initializing in main function
vector<vector<pair<int, int>>> adj;// also init in main function
struct Node{
    int u, f;
};
struct Cmp{
    bool operator()(const Node& a, const Node& b)
    {
        if(a.f != b.f) return a.f > b.f;
        return a.u > b.u;
    }
};
int heuristicManhattan(int u, int end)
{
    return abs(x[u] - x[end]) + abs(y[u] - y[end]);
}
int Astar(int start, int end, int dots)
{
    vector<int> dist(dots, INT_MAX);
    dist[start] = 0;
    vector<int> h(dots);
    for(int i = 0; i < dots; ++i) h[i] = heuristicManhattan(i, end);
    priority_queue<Node, vector<Node>, Cmp> pq;
    pq.push({start, dist[start] + h[start]});
    while(!pq.empty())
    {
        Node cur = pq.top(); pq.pop();
        int u = cur.u; int f = cur.f;
        if(u == end) break;
        if(f != h[u] + dist[u]) continue; // attention please: don't use 'visit' here because the function f(u) = h(u) + dist(u) is not guaranteed to be strictly monotonic.
        for(auto [v, w] : adj[u])
        {
            if(dist[v] > dist[u] + w)
            {
                dist[v] = dist[u] + w;
                pq.push({v, dist[v] + h[v]});
            }
        }
    }
    return dist[end];
This post is licensed under CC BY 4.0 by the author.