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

aima.core.search.online.LRTAStarAgent Maven / Gradle / Ivy

Go to download

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

There is a newer version: 3.0.0
Show newest version
package aima.core.search.online;

import java.util.HashMap;
import java.util.Set;

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.HeuristicFunction;
import aima.core.search.framework.PerceptToStateFunction;
import aima.core.util.datastructure.TwoKeyHashMap;

/**
 * Artificial Intelligence A Modern Approach (3rd Edition): Figure 4.24, page
 * 152.
*
* *
 * function LRTA*-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
 *               H, a table of cost estimates indexed by state, initially empty
 *               s, a, the previous state and action, initially null
 *           
 *   if GOAL-TEST(s') then return stop
 *   if s' is a new state (not in H) then H[s'] <- h(s')
 *   if s is not null
 *     result[s, a] <- s'
 *     H[s] <-        min LRTA*-COST(s, b, result[s, b], H)
 *             b (element of) ACTIONS(s)
 *   a <- an action b in ACTIONS(s') that minimizes LRTA*-COST(s', b, result[s', b], H)
 *   s <- s'
 *   return a
 *   
 * function LRTA*-COST(s, a, s', H) returns a cost estimate
 *   if s' is undefined then return h(s)
 *   else return c(s, a, s') + H[s']
 * 
* * Figure 4.24 LRTA*-AGENT selects an action according to the value of * neighboring states, which are updated as the agent moves about the state * space.
*
* Note: This algorithm fails to exit if the goal does not exist (e.g. * A<->B Goal=X), this could be an issue with the implementation. Comments * welcome. * * @author Ciaran O'Reilly * @author Mike Stampone */ public class LRTAStarAgent extends AbstractAgent { private OnlineSearchProblem problem; private PerceptToStateFunction ptsFunction; private HeuristicFunction hf; // persistent: result, a table, indexed by state and action, initially empty private final TwoKeyHashMap result = new TwoKeyHashMap(); // H, a table of cost estimates indexed by state, initially empty private final HashMap H = new HashMap(); // s, a, the previous state and action, initially null private Object s = null; private Action a = null; /** * Constructs a LRTA* agent with the specified search problem, percept to * state function, and heuristic 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. * @param hf * heuristic function h(n), which estimates the cost of * the cheapest path from the state at node n to a goal * state. */ public LRTAStarAgent(OnlineSearchProblem problem, PerceptToStateFunction ptsFunction, HeuristicFunction hf) { setProblem(problem); setPerceptToStateFunction(ptsFunction); setHeuristicFunction(hf); } /** * Returns the search problem of this agent. * * @return the search problem of 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 function 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; } /** * Returns the heuristic function of this agent. */ public HeuristicFunction getHeuristicFunction() { return hf; } /** * Sets the heuristic function of this agent. * * @param hf * heuristic function h(n), which estimates the cost of * the cheapest path from the state at node n to a goal * state. */ public void setHeuristicFunction(HeuristicFunction hf) { this.hf = hf; } // function LRTA*-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 H) then H[s'] <- h(s') if (!H.containsKey(sDelta)) { H.put(sDelta, getHeuristicFunction().h(sDelta)); } // if s is not null if (null != s) { // result[s, a] <- s' result.put(s, a, sDelta); // H[s] <- min LRTA*-COST(s, b, result[s, b], H) // b (element of) ACTIONS(s) double min = Double.MAX_VALUE; for (Action b : actions(s)) { double cost = lrtaCost(s, b, result.get(s, b)); if (cost < min) { min = cost; } } H.put(s, min); } // a <- an action b in ACTIONS(s') that minimizes LRTA*-COST(s', b, // result[s', b], H) double min = Double.MAX_VALUE; // Just in case no actions a = NoOpAction.NO_OP; for (Action b : actions(sDelta)) { double cost = lrtaCost(sDelta, b, result.get(sDelta, b)); if (cost < min) { min = cost; a = b; } } } // s <- s' s = sDelta; 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); } // return a return a; } // // PRIVATE METHODS // private void init() { setAlive(true); result.clear(); H.clear(); s = null; a = null; } private boolean goalTest(Object state) { return getProblem().isGoalState(state); } // function LRTA*-COST(s, a, s', H) returns a cost estimate private double lrtaCost(Object s, Action action, Object sDelta) { // if s' is undefined then return h(s) if (null == sDelta) { return getHeuristicFunction().h(s); } // else return c(s, a, s') + H[s'] return getProblem().getStepCostFunction().c(s, action, sDelta) + H.get(sDelta); } private Set actions(Object state) { return problem.getActionsFunction().actions(state); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy