All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aima.core.search.nondeterministic.AndOrSearch Maven / Gradle / Ivy

Go to download

AIMA-Java Core Algorithms from the book Artificial Intelligence a Modern Approach 3rd Ed.

The newest version!
package aima.core.search.nondeterministic;

import aima.core.agent.Action;
import aima.core.search.framework.Metrics;
import java.util.Set;

/**
 * Artificial Intelligence A Modern Approach (3rd Edition): Figure 4.11, page
 * 136.
*
* *
 * 
 * function AND-OR-GRAPH-SEARCH(problem) returns a conditional plan, or failure
 *   OR-SEARCH(problem.INITIAL-STATE, problem, [])
 * 
 * ---------------------------------------------------------------------------------
 * 
 * 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
 * 
 * ---------------------------------------------------------------------------------
 * 
 * function AND-SEARCH(states, problem, path) returns a conditional plan, or failure
 *   for each si in states do
 *      plani <- OR-SEARCH(si, problem, path)
 *      if plani = failure then return failure
 *   return [if s1 then plan1 else if s2 then plan2 else ... if sn-1 then plann-1 else plann]
 * 
 * 
* * Figure 4.11 An algorithm for searching AND-OR graphs generated by * nondeterministic environments. It returns a conditional plan that reaches a * goal state in all circumstances. (The notation [x | l] refers to the list * formed by adding object x to the front of the list l.)
*
* Note: Unfortunately, this class cannot implement the interface SearchForActions * (core.search.framework.SearchForActions) because SearchForActions.search() returns a list of * Actions to perform, whereas a nondeterministic search must return a Plan. * * @author Andrew Brown */ public class AndOrSearch { protected int expandedNodes; /** * 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: * *
	 * 
	 * function AND-OR-GRAPH-SEARCH(problem) returns a conditional plan, or failure
	 *   OR-SEARCH(problem.INITIAL-STATE, problem, [])
	 * 
	 * 
* * @param problem * @return a conditional plan or null on failure */ public Plan search(NondeterministicProblem problem) { this.expandedNodes = 0; // OR-SEARCH(problem.INITIAL-STATE, problem, []) return this.orSearch(problem.getInitialState(), problem, new Path()); } /** * Returns a conditional plan or null on failure; this function is * equivalent to the following on page 136: * *
	 * 
	 * 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
	 * 
	 * 
* * @param state * @param problem * @param path * @return a conditional plan or null on failure */ public Plan orSearch(Object state, NondeterministicProblem problem, Path path) { // do metrics this.expandedNodes++; // if problem.GOAL-TEST(state) then return the empty plan if (problem.isGoalState(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 for (Action action : problem.getActionsFunction().actions(state)) { // plan <- AND-SEARCH(RESULTS(state, action), problem, [state|path]) Plan plan = this.andSearch( problem.getResultsFunction().results(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: * *
	 * 
	 * function AND-SEARCH(states, problem, path) returns a conditional plan, or failure
	 *   for each si in states do
	 *      plani <- OR-SEARCH(si, problem, path)
	 *      if plani = failure then return failure
	 *   return [if s1 then plan1 else if s2 then plan2 else ... if sn-1 then plann-1 else plann]
	 * 
	 * 
* * @param states * @param problem * @param path * @return a conditional plan or null on failure */ public Plan andSearch(Set states, NondeterministicProblem problem, Path path) { // do metrics, setup this.expandedNodes++; Object[] _states = states.toArray(); 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] = this.orSearch(_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); } /** * Returns all the metrics of the node expander. * * @return all the metrics of the node expander. */ public Metrics getMetrics() { Metrics result = new Metrics(); result.set("expandedNodes", this.expandedNodes); return result; } }