package aima.core.search.csp; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; import java.util.List; /** * Artificial Intelligence A Modern Approach (3rd Ed.): Section 6.1, Page 202.
*
* A constraint satisfaction problem or CSP consists of three components, X, D, * and C: * * * @author Ruediger Lunde */ public class CSP { private List variables; private List domains; private List constraints; /** Lookup, which maps a variable to its index in the list of variables. */ private Hashtable varIndexHash; /** * Constraint network. Maps variables to those constraints in which they * participate. */ private Hashtable> cnet; private CSP() { } /** Creates a new CSP for a fixed set of variables. */ public CSP(List vars) { variables = new ArrayList(vars.size()); domains = new ArrayList(vars.size()); constraints = new ArrayList(); varIndexHash = new Hashtable(); cnet = new Hashtable>(); Domain emptyDomain = new Domain(new ArrayList(0)); int index = 0; for (Variable var : vars) { variables.add(var); domains.add(emptyDomain); varIndexHash.put(var, index++); cnet.put(var, new ArrayList()); } } public List getVariables() { return Collections.unmodifiableList(variables); } public int indexOf(Variable var) { return varIndexHash.get(var); } public Domain getDomain(Variable var) { return domains.get(varIndexHash.get(var)); } public void setDomain(Variable var, Domain domain) { domains.set(indexOf(var), domain); } /** * Replaces the domain of the specified variable by new domain, which * contains all values of the old domain except the specified value. */ public void removeValueFromDomain(Variable var, Object value) { Domain currDomain = getDomain(var); List values = new ArrayList(currDomain.size()); for (Object v : currDomain) if (!v.equals(value)) values.add(v); setDomain(var, new Domain(values)); } public List getConstraints() { return constraints; } /** * Returns all constraints in which the specified variable participates. */ public List getConstraints(Variable var) { return cnet.get(var); } public void addConstraint(Constraint constraint) { constraints.add(constraint); for (Variable var : constraint.getScope()) cnet.get(var).add(constraint); } /** * Returns for binary constraints the other variable from the scope. * * @return a variable or null for non-binary constraints. */ public Variable getNeighbor(Variable var, Constraint constraint) { List scope = constraint.getScope(); if (scope.size() == 2) { if (var == scope.get(0)) return scope.get(1); else if (var == scope.get(1)) return scope.get(0); } return null; } /** * Returns a copy which contains a copy of the domains list and is in all * other aspects a flat copy of this. */ public CSP copyDomains() { CSP result = new CSP(); result.variables = variables; result.domains = new ArrayList(domains.size()); result.domains.addAll(domains); result.constraints = constraints; result.varIndexHash = varIndexHash; result.cnet = cnet; return result; } }