aima.core.search.csp.ImprovedBacktrackingStrategy 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.csp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import aima.core.util.datastructure.Pair;
public class ImprovedBacktrackingStrategy extends BacktrackingStrategy {
protected Selection selectionStrategy = Selection.DEFAULT_ORDER;
protected Inference inferenceStrategy = Inference.NONE;
protected boolean isLCVHeuristicEnabled;
/** Creates a strategy which is by default equivalent to plain backtracking. */
public ImprovedBacktrackingStrategy() {
}
/** Creates a backtracking strategy with the specified features. */
public ImprovedBacktrackingStrategy(boolean enableMRV, boolean enableDeg,
boolean enableAC3, boolean enableLCV) {
if (enableMRV)
setVariableSelection(enableDeg ? Selection.MRV_DEG : Selection.MRV);
if (enableAC3)
setInference(Inference.AC3);
enableLCV(enableLCV);
}
/** Selects the algorithm for SELECT-UNASSIGNED-VARIABLE */
public void setVariableSelection(Selection sStrategy) {
selectionStrategy = sStrategy;
}
/** Selects the algorithm for INFERENCE. */
public void setInference(Inference iStrategy) {
inferenceStrategy = iStrategy;
}
/**
* Selects the least constraining value heuristic as implementation for
* ORDER-DOMAIN-VALUES.
*/
public void enableLCV(boolean state) {
isLCVHeuristicEnabled = state;
}
/**
* Starts with a constraint propagation if AC-3 is enabled and then calls
* the super class implementation.
*/
public Assignment solve(CSP csp) {
if (inferenceStrategy == Inference.AC3) {
DomainRestoreInfo info = new AC3Strategy().reduceDomains(csp);
if (!info.isEmpty()) {
fireStateChanged(csp);
if (info.isEmptyDomainFound())
return null;
}
}
return super.solve(csp);
}
/**
* Primitive operation, selecting a not yet assigned variable.
*/
@Override
protected Variable selectUnassignedVariable(Assignment assignment, CSP csp) {
switch (selectionStrategy) {
case MRV:
return applyMRVHeuristic(csp, assignment).get(0);
case MRV_DEG:
List vars = applyMRVHeuristic(csp, assignment);
return applyDegreeHeuristic(vars, assignment, csp).get(0);
default:
for (Variable var : csp.getVariables()) {
if (!(assignment.hasAssignmentFor(var)))
return var;
}
}
return null;
}
/**
* Primitive operation, ordering the domain values of the specified
* variable.
*/
@Override
protected Iterable> orderDomainValues(Variable var,
Assignment assignment, CSP csp) {
if (!isLCVHeuristicEnabled) {
return csp.getDomain(var);
} else {
return applyLeastConstrainingValueHeuristic(var, csp);
}
}
/**
* Primitive operation, which tries to prune out values from the CSP which
* are not possible anymore when extending the given assignment to a
* solution.
*
* @return An object which provides informations about (1) whether changes
* have been performed, (2) possibly inferred empty domains , and
* (3) how to restore the domains.
*/
@Override
protected DomainRestoreInfo inference(Variable var, Assignment assignment,
CSP csp) {
switch (inferenceStrategy) {
case FORWARD_CHECKING:
return doForwardChecking(var, assignment, csp);
case AC3:
return new AC3Strategy().reduceDomains(var,
assignment.getAssignment(var), csp);
default:
return new DomainRestoreInfo().compactify();
}
}
// //////////////////////////////////////////////////////////////
// heuristics for selecting the next unassigned variable and domain ordering
/** Implements the minimum-remaining-values heuristic. */
private List applyMRVHeuristic(CSP csp, Assignment assignment) {
List result = new ArrayList();
int mrv = Integer.MAX_VALUE;
for (Variable var : csp.getVariables()) {
if (!assignment.hasAssignmentFor(var)) {
int num = csp.getDomain(var).size();
if (num <= mrv) {
if (num < mrv) {
result.clear();
mrv = num;
}
result.add(var);
}
}
}
return result;
}
/** Implements the degree heuristic. */
private List applyDegreeHeuristic(List vars,
Assignment assignment, CSP csp) {
List result = new ArrayList();
int maxDegree = Integer.MIN_VALUE;
for (Variable var : vars) {
int degree = 0;
for (Constraint constraint : csp.getConstraints(var)) {
Variable neighbor = csp.getNeighbor(var, constraint);
if (!assignment.hasAssignmentFor(neighbor)
&& csp.getDomain(neighbor).size() > 1)
++degree;
}
if (degree >= maxDegree) {
if (degree > maxDegree) {
result.clear();
maxDegree = degree;
}
result.add(var);
}
}
return result;
}
/** Implements the least constraining value heuristic. */
private List