All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
aima.core.search.online.OnlineDFSAgent Maven / Gradle / Ivy
package aima.core.search.online;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.util.datastructure.Pair;
import aima.core.util.datastructure.TwoKeyHashMap;
/**
* Artificial Intelligence A Modern Approach (3rd Edition): Figure 4.21, page
* 150.
*
*
*
* function ONLINE-DFS-AGENT(s') returns an action
* inputs: s', a percept that identifies the current state
* persistent: result, a table, indexed by state and action, initially empty
* untried, a table that lists, for each state, the actions not yet tried
* unbacktracked, a table that lists, for each state, the backtracks not yet tried
* s, a, the previous state and action, initially null
*
* if GOAL-TEST(s') then return stop
* if s' is a new state (not in untried) then untried[s'] <- ACTIONS(s')
* if s is not null then
* result[s, a] <- s'
* add s to the front of the unbacktracked[s']
* if untried[s'] is empty then
* if unbacktracked[s'] is empty then return stop
* else a <- an action b such that result[s', b] = POP(unbacktracked[s'])
* else a <- POP(untried[s'])
* s <- s'
* return a
*
*
* Figure 4.21 An online search agent that uses depth-first exploration. The
* agent is applicable only in state spaces in which every action can be
* "undone" by some other action.
*
* @author Ciaran O'Reilly
*
*/
public class OnlineDFSAgent extends AbstractAgent {
private OnlineSearchProblem problem;
private PerceptToStateFunction ptsFunction;
// persistent: result, a table, indexed by state and action, initially empty
private final TwoKeyHashMap result = new TwoKeyHashMap();
// untried, a table that lists, for each state, the actions not yet tried
private final Map> untried = new HashMap>();
// unbacktracked, a table that lists,
// for each state, the backtracks not yet tried
private final Map> unbacktracked = new HashMap>();
// s, a, the previous state and action, initially null
private Object s = null;
private Action a = null;
/**
* Constructs an online DFS agent with the specified search problem and
* percept to state function.
*
* @param problem
* an online search problem for this agent to solve
* @param ptsFunction
* a function which returns the problem state associated with a
* given Percept.
*/
public OnlineDFSAgent(OnlineSearchProblem problem,
PerceptToStateFunction ptsFunction) {
setProblem(problem);
setPerceptToStateFunction(ptsFunction);
}
/**
* Returns the search problem for this agent.
*
* @return the search problem for this agent.
*/
public OnlineSearchProblem 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(OnlineSearchProblem 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;
}
// function ONLINE-DFS-AGENT(s') returns an action
// inputs: s', a percept that identifies the current state
@Override
public Action execute(Percept psDelta) {
Object sDelta = ptsFunction.getState(psDelta);
// if GOAL-TEST(s') then return stop
if (goalTest(sDelta)) {
a = NoOpAction.NO_OP;
} else {
// if s' is a new state (not in untried) then untried[s'] <-
// ACTIONS(s')
if (!untried.containsKey(sDelta)) {
untried.put(sDelta, actions(sDelta));
}
// if s is not null then do
if (null != s) {
// Note: If I've already seen the result of this
// [s, a] then don't put it back on the unbacktracked
// list otherwise you can keep oscillating
// between the same states endlessly.
if (!(sDelta.equals(result.get(s, a)))) {
// result[s, a] <- s'
result.put(s, a, sDelta);
// Ensure the unbacktracked always has a list for s'
if (!unbacktracked.containsKey(sDelta)) {
unbacktracked.put(sDelta, new ArrayList());
}
// add s to the front of the unbacktracked[s']
unbacktracked.get(sDelta).add(0, s);
}
}
// if untried[s'] is empty then
if (untried.get(sDelta).isEmpty()) {
// if unbacktracked[s'] is empty then return stop
if (unbacktracked.get(sDelta).isEmpty()) {
a = NoOpAction.NO_OP;
} else {
// else a <- an action b such that result[s', b] =
// POP(unbacktracked[s'])
Object popped = unbacktracked.get(sDelta).remove(0);
for (Pair sa : result.keySet()) {
if (sa.getFirst().equals(sDelta)
&& result.get(sa).equals(popped)) {
a = sa.getSecond();
break;
}
}
}
} else {
// else a <- POP(untried[s'])
a = untried.get(sDelta).remove(0);
}
}
if (a.isNoOp()) {
// I'm either at the Goal or can't get to it,
// which in either case I'm finished so just die.
setAlive(false);
}
// s <- s'
s = sDelta;
// return a
return a;
}
//
// PRIVATE METHODS
//
private void init() {
setAlive(true);
result.clear();
untried.clear();
unbacktracked.clear();
s = null;
a = null;
}
private boolean goalTest(Object state) {
return getProblem().isGoalState(state);
}
private List actions(Object state) {
return new ArrayList(problem.getActionsFunction()
.actions(state));
}
}