foundations of computational agents
This section describes a generic algorithm to search for a solution path in a graph. The algorithm calls procedures that can be coded to implement various search strategies.
The intuitive idea behind the generic search algorithm, given a graph, a start node, and a goal predicate, is to explore paths incrementally from the start node. This is done by maintaining a frontier (or fringe) of paths from the start node. The frontier contains all of the paths that could form initial segments of paths from the start node to a goal node. (See Figure 3.3, where the frontier is the set of paths to the gray shaded nodes.) Initially, the frontier contains the trivial path containing just the start node, and no arcs. As the search proceeds, the frontier expands into the unexplored nodes until a goal node is encountered. Different search strategies are obtained by providing an appropriate implementation of the frontier.
The generic search algorithm is shown in Figure 3.4. The frontier is a set of paths. Initially, the frontier contains the path of zero cost consisting of just the start node. At each step, the algorithm removes a path from the frontier. If is true (i.e., is a goal node), it has found a solution and returns the path . Otherwise, the path is extended by one more arc by finding the neighbors of . For every neighbor of , the path is added to the frontier. This step is known as expanding the path .
This algorithm has a few features that should be noted:
It is useful to think of the return at line 15 as a temporary return, where a caller can retry the search to get another answer by continuing the while loop. This can be implemented by having a class that keeps the state of the search and a method that returns the next solution.
If the procedure returns (“bottom”), there are no solutions, or no remaining solutions if the search has been retried.
The algorithm only tests if a path ends in a goal node after the path has been selected from the frontier, not when it is added to the frontier. There are two important reasons for this. There could be a costly arc from a node on the frontier to a goal node. The search should not always return the path with this arc, because a lower-cost solution may exist. This is crucial when the lowest-cost path is required. A second reason is that it may be expensive to determine whether a node is a goal node, and so this should be delayed in case the computation is not necessary.
If the node at the end of the selected path is not a goal node and it has no neighbors, then extending the path means removing the path from the frontier. This outcome is reasonable because this path could not be part of a path from the start node to a goal node.