Here's an algorithm that is almost A* search. Essentially it's BFS with a priority queue that uses A* priority.
frontier <- empty priority queue
frontier.insert(start) with priority g(start)+h(start)
while frontier isn't empty
vertex <- dequeue frontier
for each undiscovered neighbor of vertex
neighbor.discovered = true
neighbor.parent = vertex
frontier.insert(neighbor) with priority g(neighbor)+h(neighbor)
if neighbor == goal, stop
This algorithm is missing the parts of A* that handle this fact: the first path found to a vertex is not necessarily the shortest path to that vertex.
It's easy to come up with examples where the missing parts are crucial... for weighted graphs. For unweighted graphs, I haven't been able to come up with any.
Is it possible that this simpler version of A* is correct for unweighted graphs?
No, it is not correct for an arbitrary h
function. Here is an example. Let's assume that we have a graph with 7 vertices and the following unweighted edges: {(1, 2), (2, 3), (3, 4), (4, 6), (2, 5), (5, 6), (6, 7)}
. We can define h
in the following way: {0, 0, 0, 0, 2, 1, 0}
. The start vertex is 1
, the goal is 7.
It is easy to verify that this heuristic function is admissible. However, if we run this algorithm we will see that the path to the 6
vertex that it finds first is (1, 2, 3, 4, 6)
because f(4) = 3 + 0 < 2 + 2 = f(5)
, while the actual shortest path to it is (1, 2, 5, 6)
.