A Constraint Satisfaction Problem is a mathematical problem where the objective is to assign values to variables such that all the constraints are satisfied. Many AI applications use CSPs to solve decision-making problems. Common applications of CSPs include:
- Scheduling: It assigns resources like employees or equipment while respecting time and availability constraints.
- Planning: Organize tasks with specific deadlines or sequences.
- Resource Allocation: Distributing resources efficiently without overuse

Components
1. Variables: Things we need to find values for. For example, in a Sudoku puzzle each empty cell is a variable that needs a number.
2. Domains: The set of possible values that a variable can have. In Sudoku the domain for each cell is the numbers 1 to 9.
3. Constraints: The rules that restrict how variables can be assigned values. There are different types of constraints:
- Unary: Apply to a single variable like "this cell cannot be 5".
- Binary: Involve two variables like "these two cells cannot have the same number".
- Higher-order: Involve three or more variables like "each row in Sudoku must have all numbers from 1 to 9 without repetition".
Types
CSPs can be classified based on the number and importance of their constraints:
- Binary CSPs: Each constraint involves only two variables. Like in a scheduling problem the constraint could specify that task A must be completed before task B.
- Non-Binary CSPs: Involve more than two variables. For instance in a seating arrangement problem a constraint could state that three people cannot sit next to each other.
- Hard and Soft Constraints: Hard constraints must be strictly satisfied while soft constraints can be violated but at a certain cost. This is often used in real-world applications where not all constraints are equally important.
Representation
A constraint can be represented using a scope and a relation:
- Scope: The variables involved in the constraint.
- Relation: The valid combinations of values for those variables.
Example: For two variables V1 and V2, a constraint such as
V1 \neq V2 means that the two variables cannot have the same value.
Solving CSPs Efficiently
CSPs use search and constraint-based techniques to find assignments that satisfy all constraints. Common approaches:
1. Backtracking Algorithm
A depth-first search method that assigns values to variables and backtracks when an assignment violates a constraint.
Working:
- Select an unassigned variable and assign a value.
- Continue assigning values to other variables.
- If a constraint is violated, backtrack and try another value.
- Continue until a solution is found or all possibilities are exhausted.
Backtracking is simple and effective for many CSPs, but it can become expensive for large search spaces.
2. Forward-Checking Algorithm
Improves backtracking by checking the domains of unassigned neighboring variables after each assignment.
Working:
- Assign a value to a variable.
- Remove inconsistent values from the domains of neighboring variables.
- If any domain becomes empty, backtrack immediately.
- Continue until a solution is found.
This reduces unnecessary exploration compared with basic backtracking.
3. Constraint Propagation Algorithms
Reduces the search space by repeatedly removing values that cannot satisfy the constraints.
Working:
- Apply constraints between related variables.
- Remove values that lead to inconsistent assignments.
- Propagate these changes to other variables.
- Continue until no more values can be removed or a solution is found.
Constraint propagation is often combined with backtracking to solve CSPs more efficiently.
Example: Solving Sudoku with CSP (Backtracking Approach)
Step 1: Define the Problem (Sudoku Puzzle Setup)
We represent the Sudoku puzzle as a 9×9 grid, where 0 represents an empty cell. The print_sudoku() function displays the puzzle in a readable format.
puzzle = [[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]]
def print_sudoku(puzzle):
for i in range(9):
if i % 3 == 0 and i != 0:
print("- - - - - - - - - - - ")
for j in range(9):
if j % 3 == 0 and j != 0:
print(" | ", end="")
print(puzzle[i][j], end=" ")
print()
print("Initial Sudoku Puzzle:\n")
print_sudoku(puzzle)
Output:

Step 2: Create the CSP Solver Class
We create a CSP class to store the variables, domains and constraints. The solve() method starts the backtracking process.
class CSP:
def __init__(self, variables, domains, constraints):
self.variables = variables
self.domains = domains
self.constraints = constraints
self.solution = None
def solve(self):
assignment = {}
self.solution = self.backtrack(assignment)
return self.solution
def backtrack(self, assignment):
if len(assignment) == len(self.variables):
return assignment
var = self.select_unassigned_variable(assignment)
for value in self.order_domain_values(var, assignment):
if self.is_consistent(var, value, assignment):
assignment[var] = value
result = self.backtrack(assignment)
if result is not None:
return result
del assignment[var]
return None
Step 3: Implement Helper Functions for Backtracking
We add helper methods to select an unassigned variable, order its possible values and check whether an assignment satisfies the constraints.
def select_unassigned_variable(self, assignment):
unassigned_vars = [var for var in self.variables if var not in assignment]
return min(unassigned_vars, key=lambda var: len(self.domains[var]))
def order_domain_values(self, var, assignment):
return self.domains[var]
def is_consistent(self, var, value, assignment):
for constraint_var in self.constraints[var]:
if constraint_var in assignment and assignment[constraint_var] == value:
return False
return True
These methods must be indented inside the
CSPclass.
Step 4: Define Variables, Domains and Constraints
Each Sudoku cell is treated as a variable. Empty cells have values from 1 to 9 in their domains, while filled cells have their given value. Constraints ensure that cells in the same row, column or 3×3 subgrid contain different values.
variables = [(i, j) for i in range(9) for j in range(9)]
domains = {
var: set(range(1, 10)) if puzzle[var[0]][var[1]] == 0 else {puzzle[var[0]][var[1]]}
for var in variables
}
constraints = {}
def add_constraint(var):
constraints[var] = []
for i in range(9):
if i != var[0]:
constraints[var].append((i, var[1]))
if i != var[1]:
constraints[var].append((var[0], i))
sub_i, sub_j = var[0] // 3, var[1] // 3
for i in range(sub_i * 3, (sub_i + 1) * 3):
for j in range(sub_j * 3, (sub_j + 1) * 3):
if (i, j) != var:
constraints[var].append((i, j))
for var in variables:
add_constraint(var)
Step 5: Solve the Sudoku Puzzle Using CSP
We create a CSP object using the Sudoku variables, domains and constraints. The solve() method uses backtracking to find a valid assignment, which is then converted back into a 9×9 Sudoku grid.
csp = CSP(variables, domains, constraints)
sol = csp.solve()
solution = [[0 for _ in range(9)] for _ in range(9)]
for (i, j), val in sol.items():
solution[i][j] = val
print("\n******* Solution *******\n")
print_sudoku(solution)
Output:

You can download the source code from here.
Applications
- Scheduling: Assigning employees, rooms or resources while satisfying time and availability constraints.
- Puzzle Solving: Solving Sudoku, crosswords and N-Queens by representing puzzle elements as variables and constraints.
- Configuration: Selecting compatible components for products or systems, such as computer configurations.
- Robotics and Planning: Planning robot movements and tasks while avoiding obstacles and satisfying operational constraints.
- Natural Language Processing: Applying linguistic constraints to tasks such as sentence parsing and grammatical analysis.
Challenges
- Scalability: Large numbers of variables and constraints can create a very large search space.
- Dynamic Constraints: Real-world problems may change over time, requiring the solution to be updated.
- No Feasible Solution: Strict or conflicting constraints may make it impossible to find a valid assignment.