/** * Returns a node corresponding to a local maximum or empty if the search was * cancelled by the user. * * @param p the search problem * @return a node or empty */ // function HILL-CLIMBING(problem) returns a state that is a local maximum public Node <S, A> findNode(IProblem <S, A> p) { clearMetrics(); outcome = SearchOutcome.FAILURE; // current <- MAKE-NODE(problem.INITIAL-STATE) Node <S, A> current = nodeExpander.createRootNode(p.getInitialState()); Node <S, A> neighbor; // loop do while (!currIsCancelled) { lastState = current.getState(); metrics.set(METRIC_NODE_VALUE, getValue(current)); ICollection <Node <S, A> > children = nodeExpander.expand(current, p); // neighbor <- a highest-valued successor of current neighbor = getHighestValuedNodeFrom(children); // if neighbor.VALUE <= current.VALUE then return current.STATE if (neighbor == null || getValue(neighbor) <= getValue(current)) { if (p.testSolution(current)) { outcome = SearchOutcome.SOLUTION_FOUND; } return(current); } // current <- neighbor current = neighbor; } return(null); }
public void simpleExpand(NodeExpander nodeExpander, string propname) { Data data = new Data(); bool foundhi = false; OnChildNode l = delegate(Object from, String name, Object to) { if (name.Equals(propname) && to.Equals(data.Greeting)) { foundhi = true; } }; nodeExpander.expand(data, l); Assert.AreEqual(true, foundhi, "expected to find greeting"); }
/** * Returns a list of actions to the goal if the goal was found, a list * containing a single NoOp Action if already at the goal, or an empty list * if the goal could not be found. This template method provides a base for * tree and graph search implementations. It can be customized by overriding * some primitive operations, especially {@link #addToFrontier(Node)}, * {@link #removeFromFrontier()}, and {@link #isFrontierEmpty()}. * * @param problem * the search problem * @param frontier * the collection of nodes that are waiting to be expanded * * @return a list of actions to the goal if the goal was found, a list * containing a single NoOp Action if already at the goal, or an * empty list if the goal could not be found. */ public virtual List <Action> search(Problem problem, List <Node> frontier) { this.frontier = frontier; clearInstrumentation(); // initialize the frontier using the initial state of the problem Node root = nodeExpander.createRootNode(problem.getInitialState()); if (earlyGoalCheck) { if (SearchUtils.isGoalState(problem, root)) { return(getSolution(root)); } } addToFrontier(root); while (!(frontier.Count == 0)) { // choose a leaf node and remove it from the frontier Node nodeToExpand = removeFromFrontier(); // Only need to check the nodeToExpand if have not already // checked before adding to the frontier if (!earlyGoalCheck) { // if the node contains a goal state then return the // corresponding solution if (SearchUtils.isGoalState(problem, nodeToExpand)) { return(getSolution(nodeToExpand)); } } // expand the chosen node, adding the resulting nodes to the // frontier foreach (Node successor in nodeExpander.expand(nodeToExpand, problem)) { if (earlyGoalCheck) { if (SearchUtils.isGoalState(problem, successor)) { return(getSolution(successor)); } } addToFrontier(successor) ; } } // if the frontier is empty then return failure return(SearchUtils.failure()); }
// function SIMULATED-ANNEALING(problem, schedule) returns a solution state public Node <S, A> findNode(IProblem <S, A> p) { clearMetrics(); outcome = SearchOutcome.FAILURE; lastState = default(S); // current <- MAKE-NODE(problem.INITIAL-STATE) Node <S, A> current = nodeExpander.createRootNode(p.getInitialState()); // for t = 1 to INFINITY do int timeStep = 0; while (!currIsCancelled) { // temperature <- schedule(t) double temperature = scheduler.getTemp(timeStep); timeStep++; lastState = current.getState(); // if temperature = 0 then return current if (temperature == 0.0) { if (p.testSolution(current)) { outcome = SearchOutcome.SOLUTION_FOUND; } return(current); } updateMetrics(temperature, getValue(current)); ICollection <Node <S, A> > children = nodeExpander.expand(current, p); if (children.Size() > 0) { // next <- a randomly selected successor of current Node <S, A> next = Util.selectRandomlyFromList(children); // /\E <- next.VALUE - current.value double deltaE = getValue(next) - getValue(current); if (shouldAccept(temperature, deltaE)) { current = next; } } } return(null); }
/** * Receives a problem and a queue implementing the search strategy and * computes a node referencing a goal state, if such a state was found. * This template method provides a base for tree and graph search * implementations. It can be customized by overriding some primitive * operations, especially {@link #addToFrontier(Node)}, * {@link #removeFromFrontier()}, and {@link #isFrontierEmpty()}. * * @param problem * the search problem * @param frontier * the data structure for nodes that are waiting to be expanded * * @return a node referencing a goal state, if the goal was found, otherwise empty; */ public virtual Node <S, A> findNode(IProblem <S, A> problem, ICollection <Node <S, A> > frontier) { this.frontier = frontier; clearMetrics(); // initialize the frontier using the initial state of the problem Node <S, A> root = nodeExpander.createRootNode(problem.getInitialState()); addToFrontier(root); if (earlyGoalTest && problem.testSolution(root)) { return(getSolution(root)); } while (!isFrontierEmpty() && !currIsCancelled) { // choose a leaf node and remove it from the frontier Node <S, A> nodeToExpand = removeFromFrontier(); // only need to check the nodeToExpand if have not already // checked before adding to the frontier if (!earlyGoalTest && problem.testSolution(nodeToExpand)) { // if the node contains a goal state then return the // corresponding solution return(getSolution(nodeToExpand)); } // expand the chosen node, adding the resulting nodes to the // frontier foreach (Node <S, A> successor in nodeExpander.expand(nodeToExpand, problem)) { addToFrontier(successor); if (earlyGoalTest && problem.testSolution(successor)) { return(getSolution(successor)); } } } // if the frontier is empty then return failure return(null); }
/** * Returns a solution node, the {@link #cutoffNode}, or null (failure). */ private Node <S, A> recursiveDLS(Node <S, A> node, IProblem <S, A> problem, int limit) { // if problem.GOAL-TEST(node.STATE) then return SOLUTION(node) if (problem.testSolution(node)) { metrics.set(METRIC_PATH_COST, node.getPathCost()); return(node); } else if (0 == limit || currIsCancelled) { // else if limit = 0 then return cutoff return(cutoffNode); } else { // else // cutoff_occurred? <- false bool cutoffOccurred = false; // for each action in problem.ACTIONS(node.STATE) do metrics.incrementInt(METRIC_NODES_EXPANDED); foreach (Node <S, A> child in nodeExpander.expand(node, problem)) { // child <- CHILD-NODE(problem, node, action) // result <- RECURSIVE-DLS(child, problem, limit - 1) Node <S, A> result = recursiveDLS(child, problem, limit - 1); // if result = cutoff then cutoff_occurred? <- true if (result == cutoffNode) { cutoffOccurred = true; } else if (result != null) { // else if result != failure then return result return(result); } } // if cutoff_occurred? then return cutoff else return failure return(cutoffOccurred ? cutoffNode : null); } }