def a_star_search(graph, start, goal):
all_nodes = graph.get_all_node_ids()<EOL>if start not in all_nodes:<EOL><INDENT>raise NonexistentNodeError(start)<EOL><DEDENT>if goal not in all_nodes:<EOL><INDENT>raise NonexistentNodeError(goal)<EOL><DEDENT>came_from, cost_so_far, goal_reached = _a_star_search_internal(graph, start, goal)<EOL>if goal_reached:<EOL><INDENT>path = reconstruct_path(came_from, start, goal)<EOL>path.reverse()<EOL>return path<EOL><DEDENT>else:<EOL><INDENT>return []<EOL><DEDENT>
Runs an A* search on the specified graph to find a path from the ''start'' node to the ''goal'' node.
    Returns a list of nodes specifying a minimal path between the two nodes.
    If no path exists (disconnected components), returns an empty list.