// // PRIVATE METHODS // // function RBFS(problem, node, f_limit) returns a solution, or failure and // a new f-cost limit private SearchResult rbfs(Problem p, Node n, double node_f, double fLimit, int recursiveDepth) { setMaxRecursiveDepth(recursiveDepth); // if problem.GOAL-TEST(node.STATE) then return SOLUTION(node) if (SearchUtils.isGoalState(p, n)) { return(new SearchResult(n, fLimit)); } // successors <- [] // for each action in problem.ACTION(node.STATE) do // add CHILD-NODE(problem, node, action) into successors List <Node> successors = expandNode(n, p); // if successors is empty then return failure, infinity if (0 == successors.Count) { return(new SearchResult(null, INFINITY)); } double[] f = new double[successors.Count]; // for each s in successors do // update f with value from previous search, if any int size = successors.Count; for (int s = 0; s < size; s++) { // s.f <- max(s.g + s.h, node.f) f[s] = Math.max(evaluationFunction.f(successors.get(s)), node_f); } // repeat while (true) { // best <- the lowest f-value node in successors int bestIndex = getBestFValueIndex(f); // if best.f > f_limit then return failure, best.f if (f[bestIndex] > fLimit) { return(new SearchResult(null, f[bestIndex])); } // if best.f > f_limit then return failure, best.f int altIndex = getNextBestFValueIndex(f, bestIndex); // result, best.f <- RBFS(problem, best, min(f_limit, alternative)) SearchResult sr = rbfs(p, successors.get(bestIndex), f[bestIndex], Math.min(fLimit, f[altIndex]), recursiveDepth + 1); f[bestIndex] = sr.getFCostLimit(); // if result != failure then return result if (sr.getOutcome() == SearchResult.SearchOutcome.SOLUTION_FOUND) { return(sr); } } }
// function RECURSIVE-BEST-FIRST-SEARCH(problem) returns a solution, or // failure public List <Action> search(Problem p) { List <Action> actions = new List <Action>(); clearInstrumentation(); // RBFS(problem, MAKE-NODE(INITIAL-STATE[problem]), infinity) Node n = new Node(p.getInitialState()); SearchResult sr = rbfs(p, n, evaluationFunction.f(n), INFINITY, 0); if (sr.getOutcome() == SearchResult.SearchOutcome.SOLUTION_FOUND) { Node s = sr.getSolution(); actions = SearchUtils.actionsFromNodes(s.getPathFromRoot()); setPathCost(s.getPathCost()); } // Empty List can indicate already at Goal // or unable to find valid set of actions return(actions); }