package cc.mallet.util.search; import java.util.Iterator; import java.util.logging.Logger; import cc.mallet.util.MalletLogger; /** * Created by IntelliJ IDEA. * User: pereira * Date: Jun 19, 2005 * Time: 1:38:28 PM * A* search iterator over an underlying graph. The iterator returns * search nodes for final states in order of increasing cost to reach them * from the initial states, assuming that the heuristic cost-to-completion * function is admissible. This very simple version * assumes that we may revisit already visited states, because * we want to generate all paths to final states in order of * increasing cost. */ public class AStar implements Iterator<AStarNode> { private static Logger logger = MalletLogger.getLogger(AStar.class.getName()); private PriorityQueue q; private AStarNode answer; private boolean needNext; /** * Create an A* search iterator starting from the given initial states. * The expected size parameter gives the size of the search queue. If this * is too small, growing the queue costs more time. If this is too big, * space is wasted. * * @param initial the set of initial states * @param expectedSize the expected size of the search queue */ public AStar(AStarState[] initial, int expectedSize) { q = new MinHeap(expectedSize); for (int i = 0; i < initial.length; i++) { AStarState s = initial[i]; AStarNode n = new AStarNode(s, null, 0); n.setPriority(s.completionCost()); q.insert(n); } needNext = true; } private void lookAhead() { if (needNext) { answer = search(); needNext = false; } } public boolean hasNext() { lookAhead(); return answer != null; } public AStarNode next() { return nextAnswer(); } /** * Get the next search node for a final state. * @return a final search node */ public AStarNode nextAnswer() { lookAhead(); needNext = true; return answer; } public void remove() { throw new UnsupportedOperationException(); } private AStarNode search() { while (q.size() > 0) { AStarNode u = (AStarNode)q.extractMin(); //logger.info(u + ": " + u.getPriority()); if (u.isFinal()) { //logger.info("Final " + u); return u; } SearchNode.NextNodeIterator i = u.getNextNodes(); while (i.hasNext()) { AStarNode v = (AStarNode)i.nextNode(); double priority = v.getCost() + v.completionCost(); //logger.info("insert " + v + " at " + priority); v.setPriority(priority); q.insert(v); } } return null; } }