aima.core.search.local.SimulatedAnnealingSearch Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aima-core Show documentation
Show all versions of aima-core Show documentation
AIMA-Java Core Algorithms from the book Artificial Intelligence a Modern Approach 3rd Ed.
package aima.core.search.local;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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;
import aima.core.util.Util;
/**
* Artificial Intelligence A Modern Approach (3rd Edition): Figure 4.5, page
* 126.
*
*
*
* function SIMULATED-ANNEALING(problem, schedule) returns a solution state
*
* current <- MAKE-NODE(problem.INITIAL-STATE)
* for t = 1 to INFINITY do
* T <- schedule(t)
* if T = 0 then return current
* next <- a randomly selected successor of current
* /\E <- next.VALUE - current.value
* if /\E > 0 then current <- next
* else current <- next only with probability eˆ(/\E/T)
*
*
* Figure 4.5 The simulated annealing search algorithm, a version of stochastic
* hill climbing where some downhill moves are allowed. Downhill moves are
* accepted readily early in the annealing schedule and then less often as time
* goes on. The schedule input determines the value of the temperature T as a
* function of time.
*
* @author Ravi Mohan
* @author Mike Stampone
*/
public class SimulatedAnnealingSearch extends NodeExpander implements Search {
public enum SearchOutcome {
FAILURE, SOLUTION_FOUND
};
private final HeuristicFunction hf;
private final Scheduler scheduler;
private SearchOutcome outcome = SearchOutcome.FAILURE;
private Object lastState = null;
/**
* Constructs a simulated annealing search from the specified heuristic
* function and a default scheduler.
*
* @param hf
* a heuristic function
*/
public SimulatedAnnealingSearch(HeuristicFunction hf) {
this.hf = hf;
this.scheduler = new Scheduler();
}
/**
* Constructs a simulated annealing search from the specified heuristic
* function and scheduler.
*
* @param hf
* a heuristic function
* @param scheduler
* a mapping from time to "temperature"
*/
public SimulatedAnnealingSearch(HeuristicFunction hf, Scheduler scheduler) {
this.hf = hf;
this.scheduler = scheduler;
}
// function SIMULATED-ANNEALING(problem, schedule) returns a solution state
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 next = null;
List ret = new ArrayList();
// for t = 1 to INFINITY do
int timeStep = 0;
while (!CancelableThread.currIsCanceled()) {
// temperature <- schedule(t)
double temperature = scheduler.getTemp(timeStep);
timeStep++;
// if temperature = 0 then return current
if (temperature == 0.0) {
if (SearchUtils.isGoalState(p, current)) {
outcome = SearchOutcome.SOLUTION_FOUND;
}
ret = SearchUtils.actionsFromNodes(current.getPathFromRoot());
lastState = current.getState();
break;
}
List children = expandNode(current, p);
if (children.size() > 0) {
// next <- a randomly selected successor of current
next = Util.selectRandomlyFromList(children);
// /\E <- next.VALUE - current.value
double deltaE = getValue(p, next) - getValue(p, current);
if (shouldAccept(temperature, deltaE)) {
current = next;
}
}
}
return ret;
}
/**
* Returns e&deltaE / T
*
* @param temperature
* T, a "temperature" controlling the probability of
* downward steps
* @param deltaE
* VALUE[next] - VALUE[current]
* @return e&deltaE / T
*/
public double probabilityOfAcceptance(double temperature, double deltaE) {
return Math.exp(deltaE / temperature);
}
public SearchOutcome getOutcome() {
return outcome;
}
/**
* Returns the last state from which the simulated annealing search found a
* solution state.
*
* @return the last state from which the simulated annealing search found a
* solution state.
*/
public Object getLastSearchState() {
return lastState;
}
//
// PRIVATE METHODS
//
// if /\E > 0 then current <- next
// else current <- next only with probability e^(/\E/T)
private boolean shouldAccept(double temperature, double deltaE) {
return (deltaE > 0.0)
|| (new Random().nextDouble() <= probabilityOfAcceptance(
temperature, deltaE));
}
private double getValue(Problem p, Node n) {
// assumption greater heuristic value =>
// HIGHER on hill; 0 == goal state;
// SA deals with gardient DESCENT
return -1 * hf.h(n.getState());
}
}