public versus
protected versus private members.
vector,
list, iterator, heap.
I am worried that I didn't do a very good job of explaining A* search in class. Here is another attempt. Suppose that we are trying to find the shortest feasible schedule in a job-shop scheduling problem space. At each state x in the problem space we have two pieces of information. First, we have g(x) which gives the length of the current schedule x. Second, we have a function h(x) that attempts to estimate how much longer the schedule will become if we apply the best possible operators to x from this state onward. This function h(x) is called the heuristic function, and it always under-estimates how much longer the schedule will become.
Under these assumptions, f(x) = g(x) + h(x) is our estimate of best schedule length that can be achieved by starting at x and applying the best possible operators until a feasible solution is found. With these assumptions, A* can be written as
class state
{
...
list<state> * expand(); // method for expanding a state
float g(); // returns value of g()
float h(); // returns value of h()
float f() {return g() + h();};
// heap uses < to find the smallest element, so states will be
// expanded in this order.
int operator < (state & other) {
return f() < other.f();
}
};
// main search routine:
heap<state> frontier();
frontier.add(startState);
while (! frontier.isEmpty()) {
state current = frontier.deleteMin();
if (state.feasible()) {
cout << "The solution is " << state << endl;
break;
}
// expand state and add all children to the frontier
list<state> * l = state.expand();
listIterator<state> itr(*l);
for (itr.init(); !itr; ++itr) frontier.add(itr());
}
Consider the following search tree. Next to each node are values for
g and h. A* will expand the nodes in the order A, C, F,
B, E, K, and find the optimal solution. Best-first search would only
use g to order the nodes. It would expand the nodes in the
order A, C, F, B, D, E, K, so it would waste one expansion step.