aima.core.search.csp.AC3Strategy 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 aima.core.util.datastructure.FIFOQueue;
/**
*
* Artificial Intelligence A Modern Approach (3rd Ed.): Figure 6.3, Page 209.
*
*
*
*
* function AC-3(csp) returns false if an inconsistency is found and true otherwise
* inputs: csp, a binary CSP with components (X, D, C)
* local variables: queue, a queue of arcs, initially all the arcs in csp
* while queue is not empty do
* (Xi, Xj) = REMOVE-FIRST(queue)
* if REVISE(csp, Xi, Xj) then
* if size of Di = 0 then return false
* for each Xk in Xi.NEIGHBORS - {Xj} do
* add (Xk, Xi) to queue
* return true
*
* function REVISE(csp, Xi, Xj) returns true iff we revise the domain of Xi
* revised = false
* for each x in Di do
* if no value y in Dj allows (x ,y) to satisfy the constraint between Xi and Xj then
* delete x from Di
* revised = true
* return revised
*
*
*
* Figure 6.3 The arc-consistency algorithm AC-3. After applying AC-3, either
* every arc is arc-consistent, or some variable has an empty domain, indicating
* that the CSP cannot be solved. The name "AC-3" was used by the algorithm's
* inventor (Mackworth, 1977) because it's the third version developed in the
* paper.
*
* @author Ruediger Lunde
*/
public class AC3Strategy {
/**
* Makes a CSP consisting of binary constraints arc-consistent.
*
* @return An object which indicates success/failure and contains data to
* undo the operation.
*/
public DomainRestoreInfo reduceDomains(CSP csp) {
DomainRestoreInfo result = new DomainRestoreInfo();
FIFOQueue queue = new FIFOQueue();
for (Variable var : csp.getVariables())
queue.add(var);
reduceDomains(queue, csp, result);
return result.compactify();
}
/**
* Reduces the domain of the specified variable to the specified value and
* reestablishes arc-consistency. It is assumed that the provided CSP is
* arc-consistent before the call.
*
* @return An object which indicates success/failure and contains data to
* undo the operation.
*/
public DomainRestoreInfo reduceDomains(Variable var, Object value, CSP csp) {
DomainRestoreInfo result = new DomainRestoreInfo();
Domain domain = csp.getDomain(var);
if (domain.contains(value)) {
if (domain.size() > 1) {
FIFOQueue queue = new FIFOQueue();
queue.add(var);
result.storeDomainFor(var, domain);
csp.setDomain(var, new Domain(new Object[] { value }));
reduceDomains(queue, csp, result);
}
} else {
result.setEmptyDomainFound(true);
}
return result.compactify();
}
private void reduceDomains(FIFOQueue queue, CSP csp,
DomainRestoreInfo info) {
while (!queue.isEmpty()) {
Variable var = queue.pop();
for (Constraint constraint : csp.getConstraints(var)) {
if (constraint.getScope().size() == 2) {
Variable neighbor = csp.getNeighbor(var, constraint);
if (revise(neighbor, var, constraint, csp, info)) {
if (csp.getDomain(neighbor).isEmpty()) {
info.setEmptyDomainFound(true);
return;
}
queue.push(neighbor);
}
}
}
}
}
private boolean revise(Variable xi, Variable xj, Constraint constraint,
CSP csp, DomainRestoreInfo info) {
boolean revised = false;
Assignment assignment = new Assignment();
for (Object iValue : csp.getDomain(xi)) {
assignment.setAssignment(xi, iValue);
boolean consistentExtensionFound = false;
for (Object jValue : csp.getDomain(xj)) {
assignment.setAssignment(xj, jValue);
if (constraint.isSatisfiedWith(assignment)) {
consistentExtensionFound = true;
break;
}
}
if (!consistentExtensionFound) {
info.storeDomainFor(xi, csp.getDomain(xi));
csp.removeValueFromDomain(xi, iValue);
revised = true;
}
}
return revised;
}
}