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

aima.core.environment.vacuum.NondeterministicVacuumAgent 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.environment.vacuum;

import java.util.LinkedList;

import aima.core.agent.Action;
import aima.core.agent.Percept;
import aima.core.agent.impl.AbstractAgent;
import aima.core.agent.impl.NoOpAction;
import aima.core.search.framework.PerceptToStateFunction;
import aima.core.search.nondeterministic.AndOrSearch;
import aima.core.search.nondeterministic.IfStateThenPlan;
import aima.core.search.nondeterministic.NondeterministicProblem;
import aima.core.search.nondeterministic.Plan;

/**
 * This agent traverses the NondeterministicVacuumEnvironment using a
 * contingency plan. See page 135, AIMA3e.
 * 
 * @author Andrew Brown
 */
public class NondeterministicVacuumAgent extends AbstractAgent {
	private NondeterministicProblem problem;
	private PerceptToStateFunction ptsFunction;
	private Plan contingencyPlan;
	private LinkedList stack = new LinkedList();

	public NondeterministicVacuumAgent(PerceptToStateFunction ptsFunction) {
		setPerceptToStateFunction(ptsFunction);
	}

	/**
	 * Returns the search problem for this agent.
	 * 
	 * @return the search problem for this agent.
	 */
	public NondeterministicProblem getProblem() {
		return problem;
	}

	/**
	 * Sets the search problem for this agent to solve.
	 * 
	 * @param problem
	 *            the search problem for this agent to solve.
	 */
	public void setProblem(NondeterministicProblem problem) {
		this.problem = problem;
		init();
	}

	/**
	 * Returns the percept to state function of this agent.
	 * 
	 * @return the percept to state function of this agent.
	 */
	public PerceptToStateFunction getPerceptToStateFunction() {
		return ptsFunction;
	}

	/**
	 * Sets the percept to state functino of this agent.
	 * 
	 * @param ptsFunction
	 *            a function which returns the problem state associated with a
	 *            given Percept.
	 */
	public void setPerceptToStateFunction(PerceptToStateFunction ptsFunction) {
		this.ptsFunction = ptsFunction;
	}

	/**
	 * Return the agent contingency plan
	 * 
	 * @return the plan the agent uses to clean the vacuum world
	 */
	public Plan getContingencyPlan() {
		if (this.contingencyPlan == null) {
			throw new RuntimeException("Contingency plan not set.");
		}
		return this.contingencyPlan;
	}

	/**
	 * Execute an action from the contingency plan
	 * 
	 * @param percept
	 * @return an action from the contingency plan.
	 */
	@Override
	public Action execute(Percept percept) {
		// check if goal state
		VacuumEnvironmentState state = (VacuumEnvironmentState) this
				.getPerceptToStateFunction().getState(percept);
		if (state.getLocationState(VacuumEnvironment.LOCATION_A) == VacuumEnvironment.LocationState.Clean
				&& state.getLocationState(VacuumEnvironment.LOCATION_B) == VacuumEnvironment.LocationState.Clean) {
			return NoOpAction.NO_OP;
		}
		// check stack size
		if (this.stack.size() < 1) {
			if (this.contingencyPlan.size() < 1) {
				return NoOpAction.NO_OP;
			} else {
				this.stack.push(this.getContingencyPlan().removeFirst());
			}
		}
		// pop...
		Object currentStep = this.stack.peek();
		// push...
		if (currentStep instanceof Action) {
			return (Action) this.stack.remove();
		} // case: next step is a plan
		else if (currentStep instanceof Plan) {
			Plan newPlan = (Plan) currentStep;
			if (newPlan.size() > 0) {
				this.stack.push(newPlan.removeFirst());
			} else {
				this.stack.remove();
			}
			return this.execute(percept);
		} // case: next step is an if-then
		else if (currentStep instanceof IfStateThenPlan) {
			IfStateThenPlan conditional = (IfStateThenPlan) this.stack.remove();
			this.stack.push(conditional.ifStateMatches(percept));
			return this.execute(percept);
		} // case: ignore next step if null
		else if (currentStep == null) {
			this.stack.remove();
			return this.execute(percept);
		} else {
			throw new RuntimeException("Unrecognized contingency plan step.");
		}
	}

	//
	// PRIVATE METHODS
	//
	private void init() {
		setAlive(true);
		stack.clear();
		AndOrSearch andOrSearch = new AndOrSearch();
		this.contingencyPlan = andOrSearch.search(this.problem);
	}
}