/**
*
* @param problem
* @param frontier
* @return if goal found, the list of actions to the Goal. If already at the
* goal you will receive a List with a single NoOp Action in it. If
* fail to find the Goal, an empty list will be returned to indicate
* that the search failed.
*/
public virtual List <Action> search(Problem problem, Queue <Node> frontier)
{
this.frontier = frontier;
clearInstrumentation();
// initialize the frontier using the initial state of the problem
Node root = new Node(problem.getInitialState());
if (isCheckGoalBeforeAddingToFrontier())
{
if (SearchUtils.isGoalState(problem, root))
{
return(SearchUtils.actionsFromNodes(root.getPathFromRoot()));
}
}
frontier.Enqueue(root);
setQueueSize(frontier.Count);
while (!(frontier.Count == 0))
{
// choose a leaf node and remove it from the frontier
Node nodeToExpand = popNodeFromFrontier();
setQueueSize(frontier.Count);
// Only need to check the nodeToExpand if have not already
// checked before adding to the frontier
if (!isCheckGoalBeforeAddingToFrontier())
{
// if the node contains a goal state then return the
// corresponding solution
if (SearchUtils.isGoalState(problem, nodeToExpand))
{
setPathCost(nodeToExpand.getPathCost());
return(SearchUtils.actionsFromNodes(nodeToExpand
.getPathFromRoot()));
}
}
// expand the chosen node, adding the resulting nodes to the
// frontier
foreach (Node fn in getResultingNodesToAddToFrontier(nodeToExpand,
problem))
{
if (isCheckGoalBeforeAddingToFrontier())
{
if (SearchUtils.isGoalState(problem, fn))
{
setPathCost(fn.getPathCost());
return(SearchUtils.actionsFromNodes(fn
.getPathFromRoot()));
}
}
frontier.Enqueue(fn);
}
setQueueSize(frontier.Count);
}
// if the frontier is empty then return failure
return(failure());
}