/** * Returns a conditional plan or null on failure; this function is * equivalent to the following on page 136: * * <pre> * <code> * function OR-SEARCH(state, problem, path) returns a conditional plan, or failure * if problem.GOAL-TEST(state) then return the empty plan * if state is on path then return failure * for each action in problem.ACTIONS(state) do * plan <- AND-SEARCH(RESULTS(state, action), problem, [state | path]) * if plan != failure then return [action | plan] * return failure * </code> * </pre> * * @param state * @param problem * @param path * @return a conditional plan or null on failure */ public Plan orSearch(S state, NondeterministicProblem <S, A> problem, Path path) { // do metrics this.expandedNodes++; // if problem.GOAL-TEST(state) then return the empty plan if (problem.testGoal(state)) { return(new Plan()); } // if state is on path then return failure if (path.Contains(state)) { return(null); } // for each action in problem.ACTIONS(state) do foreach (A action in problem.getActions(state)) { // plan <- AND-SEARCH(RESULTS(state, action), problem, [state|path]) Plan plan = andSearch( problem.getResults(state, action), problem, path.prepend(state)); // if plan != failure then return [action|plan] if (plan != null) { return(plan.prepend(action)); } } // return failure return(null); }
/** * Returns a conditional plan or null on failure; this function is * equivalent to the following on page 136: * * <pre> * <code> * function AND-SEARCH(states, problem, path) returns a conditional plan, or failure * for each s<sub>i</sub> in states do * plan<sub>i</sub> <- OR-SEARCH(s<sub>i</sub>, problem, path) * if plan<sub>i</sub> = failure then return failure * return [if s<sub>1</sub> then plan<sub>1</sub> else if s<sub>2</sub> then plan<sub>2</sub> else ... if s<sub>n-1</sub> then plan<sub>n-1</sub> else plan<sub>n</sub>] * </code> * </pre> * * @param states * @param problem * @param path * @return a conditional plan or null on failure */ public Plan andSearch(ICollection <S> states, NondeterministicProblem <S, A> problem, Path path) { // do metrics, setup this.expandedNodes++; object[] _states = new object[states.Size()]; for (int i = 0; i < states.Size(); ++i) { _states[i] = states.Get(i); } Plan[] plans = new Plan[_states.Length]; // for each s_i in states do for (int i = 0; i < _states.Length; ++i) { // plan_i <- OR-SEARCH(s_i, problem, path) plans[i] = orSearch((S)_states[i], problem, path); // if plan_i = failure then return failure if (plans[i] == null) { return(null); } } // return [if s_1 then plan_1 else ... if s_n-1 then plan_n-1 else // plan_n] object[] steps = new object[plans.Length]; if (plans.Length > 0) { for (int i = 0; i < plans.Length - 1; ++i) { steps[i] = new IfStateThenPlan(_states[i], plans[i]); } steps[steps.Length - 1] = plans[plans.Length - 1]; } return(new Plan(steps)); }
/** * Searches through state space and returns a conditional plan for the given * problem. The conditional plan is a list of either an action or an if-then * construct (consisting of a list of states and consequent actions). The * final product, when printed, resembles the contingency plan on page 134. * * This function is equivalent to the following on page 136: * * <pre> * <code> * function AND-OR-GRAPH-SEARCH(problem) returns a conditional plan, or failure * OR-SEARCH(problem.INITIAL-STATE, problem, []) * </code> * </pre> * * @return a conditional plan or null on failure */ public Plan search(NondeterministicProblem <S, A> problem) { expandedNodes = 0; // OR-SEARCH(problem.INITIAL-STATE, problem, []) return(orSearch(problem.getInitialState(), problem, new Path())); }