CSE-41XX
CS-4101 AI

Lecture 07.1: Constraint Satisfaction Problems and Consistency

An introduction to CSPs, variables, domains, constraints, and enforcing arc consistency using the AC-3 algorithm.

While traditional search algorithms focus on planning (finding a sequence of actions to reach a goal), Constraint Processing focuses on assignment (identification). In these problems, the path to the goal is irrelevant; the goal itself—a complete, consistent assignment of values—is the only thing that matters.

A Constraint Satisfaction Problem (CSP) is a computational framework defined by three components:

  1. XX: A set of variables {X1,...,Xn}\{X_1, ..., X_n\}.
  2. DD: A set of domains {D1,...,Dn}\{D_1, ..., D_n\}, one for each variable.
  3. CC: A set of constraints that specify allowable combinations of values.

A state in a CSP is defined by an assignment of values to some or all variables.

  • Consistent Assignment: An assignment that does not violate any constraints.
  • Complete Assignment: Every variable is assigned a value.
  • Solution: A complete and consistent assignment.

Varieties of Constraints

Constraints limit the values that variables can take:

  • Unary constraints: Involve a single variable (e.g., SAgreenSA \neq \text{green}).
  • Binary constraints: Involve pairs of variables (e.g., SAWASA \neq WA).
  • Higher-order constraints: Involve 3 or more variables (e.g., Crypt-arithmetic puzzles).
  • Global constraints: Involve an arbitrary number of variables (e.g., Alldiff in Sudoku).
  • Preference (soft constraints): Represented by a cost for each assignment, turning the problem into a Constrained Optimization Problem (e.g., Jan prefers teaching in the morning).

Constraint Graphs

A binary CSP can be visualized as a Constraint Graph, where nodes are variables and arcs are constraints.

Map of Australia

(In the Map Coloring problem for Australia, adjacent territories cannot share the same color. The graph above shows a valid assignment where connected nodes have different colors. Notice that T (Tasmania) is an independent subproblem!)


Inference and Enforcing Consistency

Before or during the search, we can use Constraint Propagation to eliminate inconsistent values, shrinking the domains of variables and radically reducing the search space.

1. Node Consistency

A variable is node-consistent if every value in its domain satisfies all unary constraints.

  • Example: If domain of A={1,2,3,4}A = \{1, 2, 3, 4\} and constraint is A>2A > 2, we reduce the domain to DA={3,4}D_A = \{3, 4\}.

2. Arc Consistency

A variable XX is arc-consistent with another variable YY (denoted as arc XYX \rightarrow Y) if, for every value xx in the domain DXD_X, there exists at least one value yy in the domain DYD_Y that satisfies the binary constraint between XX and YY. If a value xx lacks such "support" in DYD_Y, it is pruned from DXD_X.

[!IMPORTANT] Arc Consistency is Directed: An arc XYX \rightarrow Y being consistent does not guarantee that the reverse arc YXY \rightarrow X is consistent. We must check and enforce consistency in both directions.

Concrete Step-by-Step Example

Consider two variables XX and YY with the following domains and a binary inequality constraint:

  • Domains: DX={1,2,3}D_X = \{1, 2, 3\}, DY={2,3}D_Y = \{2, 3\}
  • Constraint: X<YX < Y

Let's evaluate the arc consistency for XYX \rightarrow Y:

  1. For X=1X = 1: We look for a supporting yDYy \in D_Y such that 1<y1 < y. Both y=2y=2 and y=3y=3 work. (Kept)
  2. For X=2X = 2: We look for a supporting yDYy \in D_Y such that 2<y2 < y. The value y=3y=3 works. (Kept)
  3. For X=3X = 3: We look for a supporting yDYy \in D_Y such that 3<y3 < y. No value in DY={2,3}D_Y = \{2, 3\} satisfies this. (Removed!)

The revised domain of XX becomes DX={1,2}D_X = \{1, 2\}.


The AC-3 Algorithm

The AC-3 algorithm (Mackworth, 1977) is the standard method for enforcing arc consistency across an entire constraint graph. It maintains a queue of arcs that need to be checked. Whenever a variable's domain is reduced, any constraints pointing into that variable must be re-evaluated, as their supporting values may have disappeared.

Pseudocode

function AC-3(csp) returns false if inconsistency is found, true otherwise
    inputs: csp, a binary CSP with variables X, domains D, constraints C
    local variables: queue, a queue of arcs, initially containing all 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 // Domain Wipe Out (DWO) - no solution exists
            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 satisfies the constraint between Xi and Xj then
            delete x from Di
            revised = true
    return revised

Walkthrough: The Divisibility Constraint Problem (Rina Dechter's Example)

To see AC-3 in action, let's trace a network of three variables {x,y,z}\{x, y, z\} with two divisibility constraints:

  • Constraints: zz divides xx and zz divides yy (i.e., x/zx/z and y/zy/z are integers).
  • Initial Domains:
    • Dx={2,5}D_x = \{2, 5\}
    • Dy={2,4}D_y = \{2, 4\}
    • Dz={2,5}D_z = \{2, 5\}

Let's initialize the queue of directed arcs: Queue={(x,z),(z,x),(y,z),(z,y)}\text{Queue} = \{(x, z), (z, x), (y, z), (z, y)\}

  1. Process (z,y)(z, y): We check if every zDzz \in D_z has a multiplier in DyD_y (such that zz divides yy).
    • z=2z = 2: Supported by y=2y = 2 and y=4y = 4 (222 \mid 2 and 242 \mid 4). (Kept)
    • z=5z = 5: 55 does not divide 22 or 44. No support! We delete 55 from DzD_z.
    • Domain update: Dz={2}D_z = \{2\}.
    • Propagation: Since DzD_z changed, we add neighbors of zz (except yy) pointing to zz back to the queue. The arc (x,z)(x, z) is already in the queue, so no new additions are needed.
  2. Process (x,z)(x, z): We check if every xDxx \in D_x has a divisor in Dz={2}D_z = \{2\}.
    • x=2x = 2: Supported by z=2z = 2 (222 \mid 2). (Kept)
    • x=5x = 5: z=2z = 2 does not divide 55. No support! We delete 55 from DxD_x.
    • Domain update: Dx={2}D_x = \{2\}.
    • Propagation: Since DxD_x changed, we must add (z,x)(z, x) to the queue (already there).
  3. Process (z,x)(z, x): Check if every zDz={2}z \in D_z = \{2\} divides some xDx={2}x \in D_x = \{2\}. Yes, 22 divides 22. (No change).
  4. Process (y,z)(y, z): Check if every yDy={2,4}y \in D_y = \{2, 4\} has a divisor in Dz={2}D_z = \{2\}.
    • y=2y = 2: Supported by z=2z = 2.
    • y=4y = 4: Supported by z=2z = 2. (No change).

The queue is now empty. The algorithm terminates successfully, returning: Dx={2},Dy={2,4},Dz={2}D_x = \{2\}, \quad D_y = \{2, 4\}, \quad D_z = \{2\} This network is now completely arc-consistent!


The Arc Consistency Family: From AC-1 to AC-4

The evolution of arc consistency algorithms reflects a classic computer science trade-off between simplicity, time complexity, and memory overhead.

AlgorithmMechanismTime ComplexitySpace ComplexityPros & Cons
AC-1Brute Force: If any variable's domain is revised during a pass over all arcs, it re-checks every single arc from scratch.O(d3ne)O(d^3 \cdot n \cdot e)O(e)O(e)Simple but highly redundant; performs many useless constraint checks.
AC-2Variable-Based Queueing: Organizes checks by variable. When DiD_i is revised, only arcs pointing into XiX_i are queued.O(ed3)O(e \cdot d^3)O(e)O(e)More selective than AC-1, but superseded by the simpler arc-oriented AC-3.
AC-3Arc-Based Queueing: Maintains a queue of individual directed arcs. Only propagates updates along affected constraints.O(ed3)O(e \cdot d^3)O(e)O(e)Most popular: Excellent average-case performance and very low space requirements.
AC-4Support Lists & Counters: Pre-computes and stores how many supports each value has, updating counters dynamically.O(ed2)O(e \cdot d^2)O(ed2)O(e \cdot d^2)Optimal worst-case time complexity, but high memory overhead and complex to implement.

(Where nn is the number of variables, dd is the maximum domain size, and ee is the number of binary constraint arcs.)

On this page