I. Terminology Last time we took a look at an informal description of a generic search procedure. Today we'll get a little bit more formal so that we can start to implement this procedure in CILOG. As a step in that direction, here are some possibly new vocabulary words for you so that we can all speak the same language: A directed graph consists of a set of nodes and a set of ordered pairs called arcs (or sometimes links). A node n2 is a neighbor of node n1 if there is an arc from n1 to n2. A path is an ordered sequence of nodes such that there is an arc between any two consecutive nodes in the path. A cycle is a nonempty path with a start node and end node the same. A directed graph without cycles is called a directed acyclic graph. Now let's consider the generic graph search algorithm from the previous lecture: Given a set of start nodes, a set of goal nodes, and a graph: make a "list" of the start nodes - let's call it the "frontier" repeat if no nodes on the frontier then terminate with failure choose one node from the frontier and remove it if the chosen node matches the goal node then terminate with success else put next nodes (the neighbors of the chosen node) on the frontier end repeat If you were to go back to the slides from the previous lecture as well and walk through the big example, you might recognize that the search that was performed could be characterized as a depth-first search. That depth-first behavior emerged because of assumptions we made about how nodes were placed on and taken off the frontier list. Here are those assumptions made explicit: Given a set of start nodes, a set of goal nodes, and a graph: make a "list" of the start nodes - let's call it the "frontier" repeat if no nodes on the frontier then terminate with failure choose one node from the FRONT of the frontier and remove it if the chosen node matches the goal node then terminate with success else put next nodes (the neighbors of the chosen node) on the FRONT of the frontier end repeat Those two little changes (in capital letters) turn generic search into depth-first search, and you can see how it works in more detail in today's slides. You'll also find the Datalog and CILOG descriptions of the depth-first search algorithm. Furthermore, by making just one small change to the depth-first algorithm, we'll get breadth-first search as seen in the slides. Here's the one small change: Given a set of start nodes, a set of goal nodes, and a graph: make a "list" of the start nodes - let's call it the "frontier" repeat if no nodes on the frontier then terminate with failure choose one node from the frontier of the frontier and remove it if the chosen node matches the goal node then terminate with success else put next nodes (the neighbors of the chosen node) on the BACK of the frontier end repeat Another way to look at this is in terms of how the frontier data structure is implemented. If the frontier acts as a stack, with nodes being added and removed from the same end of the data structure so that the node most recently added is the first to be taken off and explored, you get depth-first search behavior. On the other hand, if the frontier acts as a queue such that the node to be explored next is taken from one end while new neighbor nodes are added to the frontier at the other end, you'll see breadth-first search behavior. As we'll see, there are still other approaches to search to be built upon these.
Last revised: October 26, 2004