home *** CD-ROM | disk | FTP | other *** search
- #include "graph.h"
-
- /* BEST_NODE_
-
- The constructor passes the start node, goal node and the number of
- operators to SEARCH_.
-
- */
-
- BEST_::BEST_(BEST_NODE_ *start, BEST_NODE_ *goal, int op)
- :SEARCH_(start, goal, op)
- // This way the G- and F-values of the start node won't be computed,
- // but this is not very problematic.
- {
- }
-
-
-
- /* ADD
-
- This functions examines each node that it is offered and decides
- wether or not it should be added to OPEN.
- First, it fills in the node's G- and F-values by calling compute_g()
- and compute_f(). Next, it tries to lookup this node in OPEN and/or
- in CLOSED. If the node is already on OPEN, but it's F-value is worse
- than the older node (this is determined by eval()) it can simply be
- thrown away, if it's better, the older node will be thrown away
- (by remove_found()) and the new node will be added to OPEN
- (by insert()). The same goes if a node is found to be already on
- CLOSED. A node that is neither on OPEN nor on CLOSED can simply be
- added to OPEN (by insert(), which creates an ordered list).
-
- */
-
- int BEST_::add(NODE_ *succ)
- {
- BEST_NODE_
- *parent,
- *old = NULL,
- *bsucc = (BEST_NODE_ *) succ;
-
- int
- g;
-
- parent = (BEST_NODE_ *) bsucc->getparent();
-
- g = parent->get_g() + compute_g(*bsucc);
- /* a node's g-value is composed of the overall cost so far, i.e, the
- the cost of getting from the start node to the parent of this node
- and the added cost of getting from the parent to this node. */
- bsucc->set_g(g);
- bsucc->set_f(g + compute_h(*bsucc));
- /* a node's f-value consists of its g-value and the value returned by
- the heurisctic function compute_h(). */
-
- if ((old = (BEST_NODE_ *) open.lookup(*succ)) != NULL)
- { // node already on open
- if (bsucc->eval(*old) < 0) // new node better
- {
- open.remove_found(DEALLOC); // remove & destroy old node
- open.insert(*bsucc); // add this node to the graph
- return(1);
- }
- return(0);
- }
- if ((old = (BEST_NODE_ *) closed.lookup(*succ)) != NULL)
- { // node already on closed
- if (bsucc->eval(*old) < 0) // new node better
- {
- closed.remove_found(DEALLOC); // remove & destroy old node
- open.insert(*bsucc);
- return(1);
- }
- return(0);
- }
- // node neither on open nor on closed
- open.insert(*bsucc);
- return(1);
- }
- /*
- A disadvantage of this method is that if a node is found to be
- already on CLOSED and if it's better than the old node it will again
- be added to OPEN, meaning that it will re-examined: its successors
- will be again be generated etc, which may result in a lot of work being
- done twice. A better solution that circumvents this problem is described
- by Rich, 80/81 (note that in the algorithm that Ritch describes nodes
- also have a pointer to their successors beside a pointer to their parent,
- meaning that the algorithm we use would have to undergo major changes to
- support this solution).
- */
-