ALGORITHMS - A*
Algorithm A* is a best-first search algorithm that relies on an open list and a closed list to find a path that is both optimal and complete towards the goal. It works by combining the benefits of the uniform-cost search and greedy search algorithms. A* makes use of both elements by including two separate path finding functions in its algorithm that take into account the cost from the root node to the current node and estimates the path cost from the current node to the goal node.
The first function is g(n), which calculates the path cost between the start node and the current node. The second function is h(n), which is a heuristic to calculate the estimated path cost from the current node to the goal node. F(n) = g(n) + h(n). It represents the path cost of the most efficient estimated path towards the goal. A* continues to re-evaluate both g(n) and h(n) throughout the search for all of the nodes that it encounters in order to arrive at the minimal cost path to the goal. This algorithm is extremely popular for pathfinding in strategy computer games.
The process for A* is basically this:
1. Create an open list and a closed list that are both empty. Put the start node in the open list.
2. Loop this until the goal is found or the open list is empty:
a. Find the node with the lowest F cost in the open list and place it in the closed list.
b. Expand this node and for the adjacent nodes to this node:
i. If they are on the closed list, ignore.
ii. If not on the open list, add to open list, store the current node as the parent for this adjacent node, and calculate the F,G, H costs of the adjacent node.
iii. If on the open list, compare the G costs of this path to the node and the old path to the node. If the G cost of using the current node to get to the node is the lower cost, change the parent node of the adjacent node to the current node. Recalculate F,G,H costs of the node.
3. If open list is empty, fail.
The terms locally finite, admissible, and monotonic all aid in the understanding of when A* can be expected to be complete, meaning that it finds a solution, and optimal, meaning that it finds the solution with the lowest path cost. A locally finite graph is one where none of the nodes on the graph have an infinite branching factor, thus none of the node paths branch forever. A branching factor of a node refers to the amount of new nodes that can be expanded from that node.
A heuristic is admissible if it is always optimistic; it either underestimates the path cost to the goal or provides a correct estimate for the path cost to the goal, but it never overestimates the path cost to the goal.
A heuristic is monotonic if in every path from the root to the goal the total estimated path cost does not decrease as the heuristic goes down a node tree. (illustration) Nonmonotonic heuristics can be made monotonic by the pathmax equation, which compares the estimated path cost of a node with the estimated path cost of its parent node. It then uses the higher path cost for estimation. Therefore, if the heuristic's estimated path cost decreases from one node to its child node, the pathmax equation uses the path cost of the parent node so that it is not evaluated as decreasing.
Fig.1 Illustration of a map featuring monoticity with contours at 380, 400 and 420.
A* is complete and optimal on graphs that are locally finite where the heuristics are admissible and monotonic.
A* must be locally finite, because if there exist an infinite amount of nodes where the estimated path cost, f(n), is less than the actual goal path cost then the algorithm could continue to explore these nodes without end, and it will be neither complete nor optimal.
How does monotocity affect A*'s completeness? Because A* is monotonic, the path cost increases as the node gets further from the root. Contours can be drawn to show areas where the estimated path cost, the f(n), for the nodes inside the areas are lower than or equal to the path cost for the outer bounds of the contours. These contours can be drawn as larger and larger areas that increase outwards as the f(n) for the outer bound of these contours increases. The first solution found is optimal since it is the first band where the f(n) for the contour is equal to the path cost for the goal. All the contours outside of this solution will have a higher f cost.
A*'s optimality is proved by contradiction. First, it is assumed that g is an optimal goal state with a path cost of f(g), that s is a suboptimal goal state with a path cost of g(s) > f(g), and that n is a node on an optimal path to g. We are assuming that A* selects s (the suboptimal goal) instead of n (the node on the optimal path) from the open list.
Since h is admissible, (optimistic), f(g) >= f(n). (The actual path cost is greater than or equal to the path cost estimated by the heuristic at n.)
If n is not chosen over s for expansion by A*, f(n) >= f(s). (The heuristic chooses the node with the lowest estimated F path cost.)
Thus, f(g) >= f(s).
Since s is a goal state, h(s) = 0. (The estimation from the
current node to the final node must be 0.)
So f(s) = g(s). (f(s) = g(s) + h(s).)
Thus, f(g) >= g(s). This contradicts the statement that
S is suboptimal so it must be true that A* never chooses a suboptimal path.
Since A* only can have as a solution a node that it has selected for expansion,
it is optimal.