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

aima.core.search.local.HillClimbingSearch 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.local;

import java.util.ArrayList;
import java.util.List;

import aima.core.agent.Action;
import aima.core.search.framework.HeuristicFunction;
import aima.core.search.framework.Node;
import aima.core.search.framework.NodeExpander;
import aima.core.search.framework.Problem;
import aima.core.search.framework.Search;
import aima.core.search.framework.SearchUtils;
import aima.core.util.CancelableThread;

/**
 * Artificial Intelligence A Modern Approach (3rd Edition): Figure 4.2, page
 * 122.
*
* *
 * function HILL-CLIMBING(problem) returns a state that is a local maximum
 *                    
 *   current <- MAKE-NODE(problem.INITIAL-STATE)
 *   loop do
 *     neighbor <- a highest-valued successor of current
 *     if neighbor.VALUE <= current.VALUE then return current.STATE
 *     current <- neighbor
 * 
* * Figure 4.2 The hill-climbing search algorithm, which is the most basic local * search technique. At each step the current node is replaced by the best * neighbor; in this version, that means the neighbor with the highest VALUE, * but if a heuristic cost estimate h is used, we would find the neighbor with * the lowest h. * * @author Ravi Mohan * @author Mike Stampone */ public class HillClimbingSearch extends NodeExpander implements Search { public enum SearchOutcome { FAILURE, SOLUTION_FOUND }; private HeuristicFunction hf = null; private SearchOutcome outcome = SearchOutcome.FAILURE; private Object lastState = null; /** * Constructs a hill-climbing search from the specified heuristic function. * * @param hf * a heuristic function */ public HillClimbingSearch(HeuristicFunction hf) { this.hf = hf; } /** * Returns a list of actions to the local maximum if the local maximum was * found, a list containing a single NoOp Action if already at the local * maximum, or an empty list if the search was canceled by the user. * * @param p * the search problem * * @return a list of actions to the local maximum if the local maximum was * found, a list containing a single NoOp Action if already at the * local maximum, or an empty list if the search was canceled by the * user. */ // function HILL-CLIMBING(problem) returns a state that is a local maximum public List search(Problem p) throws Exception { clearInstrumentation(); outcome = SearchOutcome.FAILURE; lastState = null; // current <- MAKE-NODE(problem.INITIAL-STATE) Node current = new Node(p.getInitialState()); Node neighbor = null; // loop do while (!CancelableThread.currIsCanceled()) { List children = expandNode(current, p); // neighbor <- a highest-valued successor of current neighbor = getHighestValuedNodeFrom(children, p); // if neighbor.VALUE <= current.VALUE then return current.STATE if ((neighbor == null) || (getValue(neighbor) <= getValue(current))) { if (SearchUtils.isGoalState(p, current)) { outcome = SearchOutcome.SOLUTION_FOUND; } lastState = current.getState(); return SearchUtils.actionsFromNodes(current.getPathFromRoot()); } // current <- neighbor current = neighbor; } return new ArrayList(); } /** * Returns SOLUTION_FOUND if the local maximum is a goal state, or FAILURE * if the local maximum is not a goal state. * * @return SOLUTION_FOUND if the local maximum is a goal state, or FAILURE * if the local maximum is not a goal state. */ public SearchOutcome getOutcome() { return outcome; } /** * Returns the last state from which the hill climbing search found the * local maximum. * * @return the last state from which the hill climbing search found the * local maximum. */ public Object getLastSearchState() { return lastState; } // // PRIVATE METHODS // private Node getHighestValuedNodeFrom(List children, Problem p) { double highestValue = Double.NEGATIVE_INFINITY; Node nodeWithHighestValue = null; for (int i = 0; i < children.size(); i++) { Node child = (Node) children.get(i); double value = getValue(child); if (value > highestValue) { highestValue = value; nodeWithHighestValue = child; } } return nodeWithHighestValue; } private double getValue(Node n) { // assumption greater heuristic value => // HIGHER on hill; 0 == goal state; return -1 * hf.h(n.getState()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy