Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 92

Backtracking for CSPs

Recommended resources

Hello! Welcome to your fourth lesson in the "Artificial Intelligence: Search and Reasoning" module.

In our last lesson, you learned the crucial first step in solving a whole class of AI problems: how to formulate them as Constraint Satisfaction Problems (CSPs) by identifying variables, domains, and constraints. We saw how puzzles like Sudoku and map coloring fit this framework.

Now that we know how to describe these problems, our goal today is to learn how to solve them. The learning outcome for this lesson is to apply the backtracking algorithm to solve Constraint Satisfaction Problems. Backtracking is a fundamental and intuitive search technique that systematically explores possibilities to find a valid solution.

1. The Core Idea of Backtracking

At its heart, backtracking is a form of depth-first search. Imagine you're walking through a maze. You follow a path until you either reach the exit (a solution) or hit a dead end. When you hit a dead end, you "backtrack" to the last intersection where you had a choice and try a different path.

The backtracking algorithm for CSPs works in the same way:

  1. Assign: Pick an unassigned variable and give it a value from its domain. This is like choosing a path at an intersection.
  2. Check: Check if this new partial assignment violates any constraints.
  3. Recurse:
    • If it's consistent, move on to the next variable and repeat the process.
    • If it's inconsistent (a dead end), undo the assignment and try the next available value for the current variable.
  4. Backtrack: If you run out of values for the current variable, it means the previous decision was wrong. You "backtrack" to the previous variable and try a new value for it.

To see this in action with a very simple problem, let's watch a short video.

Constraint Satisfaction: introduction

This video, 'Constraint Satisfaction: introduction', provides a clear, step-by-step walkthrough of the backtracking algorithm on a small, manageable problem.

Watch the video from 01:41 to 07:00. Pay close attention to how the algorithm systematically tries values for variables A, B, and C, and how it backtracks when a constraint is violated.

This simple example shows the essence of the algorithm: a systematic, incremental search that prunes branches of the search tree as soon as a constraint is violated.


2. The Backtracking Algorithm: Pseudocode

Now that you have the intuition, let's look at the general structure of the algorithm. This is often implemented as a recursive function. The article below provides a clean pseudocode representation.

How to Solve Constraint Satisfaction Problems

The article 'How to Solve Constraint Satisfaction Problems' from Baeldung provides a formal pseudocode for the backtracking algorithm.

Read sections 4 ('The Backtracking Solver') and 4.1 ('Pseudocode'). Focus on understanding the structure of the recursive BACKTRACK function. Notice how it checks for completeness, selects a variable, loops through values, and makes a recursive call.

The core of the algorithm is the recursive BACKTRACK function:

  • Base Case: If the assignment is complete (all variables have values), a solution has been found.
  • Recursive Step:
    1. Select an unassigned variable.
    2. For each value in that variable's domain:
    3. Check if assigning this value is consistent with the current assignment.
    4. If it is, add it to the assignment and make a recursive call to BACKTRACK.
    5. If the recursive call finds a solution, we're done! Pass the solution up.
    6. If not, remove the assignment (this is the "backtracking" step) and try the next value.
  • Failure: If the loop finishes without finding a solution, it means there's no solution from this partial assignment, so return failure.

3. Applying Backtracking: The 4-Queens Problem

Let's apply this algorithm to a more complex and visual problem: the 4-Queens problem. The goal is to place four queens on a 4x4 chessboard so that no two queens can attack each other.

Formulation as a CSP:

  • Variables: , where represents the row of the queen in column .
  • Domain: For each variable, the domain is representing the four rows.
  • Constraints: For any two queens in columns and :
    • They cannot be in the same row: .
    • They cannot be on the same diagonal: .

The following lecture notes provide an exceptionally detailed trace of the backtracking algorithm solving this problem.

Lecture 4 Constraint Satisfaction Problems

These lecture notes, 'Lecture 4 Constraint Satisfaction Problems' from the University of Waterloo, give a fantastic visual trace of backtracking for the 4-Queens problem.

Read the section titled 'Weโ€™ll trace the backtracking algorithm on the 4-queens problem' (starts on page 10 and ends on page 14). Follow the search tree expansion step-by-step. The diagrams showing the board and the crossed-out squares are key to understanding the process of checking constraints and backtracking. Finally, read the summary right after the trace, which highlights why this is more efficient than a simple search.

This image provides a high-level summary of the search tree explored during the 4-Queens problem. The 'X' marks show where the algorithm pruned the search because a constraint was violated.

Backtracking Example: 4-Queens Problem
A visual representation of the backtracking search for the 4-Queens problem. Each node shows a partial assignment. The algorithm explores a branch (goes deeper) as long as constraints are met and backtracks when a dead end is reached.
Test your understanding!

In the 4-Queens trace from the lecture notes, the algorithm explores the partial assignment (0). It then explores (0, 2), which leads to a dead end. After backtracking from (0, 2), what is the next partial assignment it tries, and why?

Show answer

The next partial assignment it tries is (0, 3).

Here's why:

  1. The algorithm fails to find a valid placement for the third queen after the assignment (0, 2).
  2. It backtracks from trying to place the third queen.
  3. It then backtracks from the assignment of the second queen, X1 = 2.
  4. It proceeds to the next available value for X1, which is 3. This leads to the new partial assignment (0, 3).

4. Making Backtracking Smarter with Inference

Plain backtracking works, but it can still explore paths that are clearly doomed to fail. We can make it more efficient with inferenceโ€”using the constraints to deduce that some future choices are impossible.

A simple yet powerful form of inference is forward checking.

Forward Checking: When we assign a value to a variable , we look at all the unassigned variables connected to by a constraint. For each of these neighbors, we remove any values from their domains that are now inconsistent with the new assignment to .

If this process ever causes a variable's domain to become empty, we know the current assignment to is bad, and we can backtrack immediately without going any deeper.

The following video demonstrates this concept using the map coloring problem.

Backtracking Example: Australia Map Coloring
The search space for a map coloring problem, which can be explored using backtracking. Adding forward checking prunes this tree significantly.

Constraint Satisfaction Problems - Backtracking Search // Finding solutions to CSPs

This video, 'Constraint Satisfaction Problems - Backtracking Search', provides a brilliant comparison between plain backtracking and backtracking with forward checking.

This video is a bit long, so focus on these key segments: Plain Backtracking (08:00 - 11:30): First, watch this part to see how the algorithm works on the Australia map coloring problem without inference. Notice how it tries an inconsistent assignment (nt = r) and immediately backtracks. Introducing Forward Checking (14:04 - 17:11): Next, watch this segment where the presenter explains what forward checking is. Pay attention to how assigning wa = red causes red to be removed from the domains of nt and sa. Backtracking with Forward Checking (17:11 - 21:00): Finally, watch this part of the detailed walkthrough. See how each assignment leads to domain reductions for neighboring variables. This makes the search much more efficient.

By pruning the domains of future variables, forward checking helps the algorithm detect failure much earlier, saving a huge amount of computational work.


Conclusion

Today, you have learned the mechanics of the backtracking algorithm, a cornerstone for solving a wide array of problems in AI. You saw how it systematically builds and revises a solution, and how simple enhancements like forward checking can make it significantly more powerful.

Key Takeaways:

  • Backtracking is a depth-first search algorithm that solves CSPs by incrementally building a solution and undoing steps when a constraint is violated.
  • It operates on partial assignments, checking for consistency at each step before proceeding.
  • When a path leads to a dead end (no valid values for a variable), the algorithm backtracks to a previous decision point to explore an alternative.
  • Inference techniques, like forward checking, can dramatically improve efficiency by pruning the search space, removing inconsistent values from the domains of future variables.

Preview of the Next Lesson:

So far, our problems have been "static" puzzles. In the next lesson, "Implement the Minimax algorithm for adversarial, two-player games," we will shift our focus to dynamic environments where we must reason about the actions of an opponent. You will learn the foundational algorithm for game-playing AI, which is essential for everything from chess to more complex strategic games.