Act5
Act5
Constraint Satisfaction Problems (CSPs) involve finding solutions to problems defined by a set
of constraints that variables must satisfy. A CSP is typically represented by:
To solve a CSP:
1. Define the variables and domains: Specify what needs to be solved and the potential
solutions.
2. Apply constraints: Identify rules the solutions must obey.
3. Search for a solution: Use algorithms (e.g., backtracking, forward-checking) to explore
possible combinations and find one or more solutions.
1. Scheduling: Assigning tasks to time slots while meeting constraints (e.g., exam
scheduling).
2. Map Coloring: Assigning colors to regions on a map so that no two adjacent regions
share the same color.
3. Resource Allocation: Optimally distributing resources in constrained environments.
4. Puzzle Solving: Solving Sudoku or crossword puzzles.
5. Machine Learning: Tuning hyperparameters with constraints or managing resource-
constrained training.
4. Example: Solving a CSP (Map Coloring)
In the map-coloring problem, the goal is to assign colors to regions such that no two adjacent
regions share the same color.
Python Example:
def map_coloring():
# Create a problem instance
problem = Problem()
# Get solutions
solutions = problem.getSolutions()
return solutions
# Print solutions
print(map_coloring())
Questions
1. What are the three key components of a Constraint Satisfaction Problem (CSP)?
Explain each with an example.
1. Variables
Variables are the entities that need to be assigned values from a specific domain. Each
variable represents an element of the problem that needs a solution.
Example: In a Sudoku puzzle, each cell in the grid is a variable. For a standard 9x9
Sudoku, there are 81 variables, each representing one cell in the grid.
2. Domains
A domain is the set of possible values that each variable can take. The domain defines the
range of values that can be assigned to the variables.
Example: In the Sudoku puzzle, the domain for each cell (variable) is the set of numbers
{1, 2, 3, 4, 5, 6, 7, 8, 9}. Each cell can be assigned any value from this domain,
depending on the constraints.
3. Constraints
Constraints are the rules that restrict the values that the variables can simultaneously take.
Constraints specify the relationships among variables and must be satisfied to solve the
problem.
Each row must contain all the numbers from 1 to 9 without repetition.
Each column must contain all the numbers from 1 to 9 without repetition.
Each of the nine 3x3 sub-grids must contain all the numbers from 1 to 9 without
repetition.
In solving a CSP, the goal is to find an assignment of values to the variables such that all
constraints are satisfied. CSP techniques are widely used in various fields such as
scheduling, planning, resource allocation, and more.
2. Explain how backtracking can be used to solve CSPs. What are its advantages and
limitations?
In a Sudoku puzzle:
Advantages of Backtracking
Limitations of Backtracking
1. Inefficiency for Large Problems: As the number of variables and constraints increases,
the algorithm can become very slow due to the exponential growth of the search space.
2. Redundant Work: It may repeatedly explore the same partial solutions, especially in
problems with overlapping subproblems.
3. Lack of Heuristics: Without additional heuristics or optimizations, the algorithm may
spend a lot of time exploring unpromising paths.
Enhancements to Backtracking
To mitigate some of these limitations, several enhancements can be applied:
Forward Checking: Helps by looking ahead and eliminating values that would cause a
constraint violation in future assignments.
Constraint Propagation: Techniques like arc-consistency (AC-3) can further reduce the
search space by enforcing constraints.
Heuristics: Using heuristics like the Minimum Remaining Values (MRV) can prioritize
variables that are more constrained, improving efficiency.
3. Modify the given Python code to solve a Sudoku puzzle. Provide your
implementation below.
Answer 3: To modify the given Python code to solve a Sudoku puzzle using a similar approach
(constraint satisfaction problem), we need to:
Here's how you can modify the code to solve a Sudoku puzzle:
def sudoku_solver(puzzle):
problem = Problem()
n=9
# Add variables (cells in the Sudoku grid) with domains (numbers 1-9)
# Add constraints: Each row, column, and 3x3 subgrid must have unique numbers
for i in range(n):
problem.addConstraint(AllDifferentConstraint(), subgrid_cells)
solutions = problem.getSolutions()
return solutions
# Example puzzle:
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]
solutions = sudoku_solver(puzzle)
if solutions:
solution = solutions[0]
print("Solution:")
else:
Explanation:
1. Variables: Each cell in the 9x9 grid is a variable, and its domain is the set of possible
numbers (1 to 9).
2. Constraints:
o Row constraints: Each row must contain unique numbers (no repetition).
o Column constraints: Each column must also contain unique numbers.
o Subgrid constraints: Each of the nine 3x3 subgrids must have unique numbers.
3. Given Puzzle Values: For cells that are pre-filled (non-zero), we add a constraint to fix
the value in that cell.
Output:
The program will print the solved Sudoku puzzle if a solution exists. For example, the
solution for the given puzzle might look like this:
Solution:
[5, 3, 4, 6, 7, 8, 9, 1, 2]
[6, 7, 2, 1, 9, 5, 3, 4, 8]
[1, 9, 8, 3, 4, 2, 5, 6, 7]
[8, 5, 9, 7, 6, 1, 4, 2, 3]
[4, 2, 6, 8, 5, 3, 7, 9, 1]
[7, 1, 3, 9, 2, 4, 8, 5, 6]
[9, 6, 1, 5, 3, 7, 2, 8, 4]
[2, 8, 7, 4, 1, 9, 6, 3, 5]
[3, 4, 5, 2, 8, 6, 1, 7, 9]
If there is no solution (for example, if the puzzle is invalid), it will print "No solution
found".
Problem Formulation
Variables:
Domains:
Classes: The set of all classes that need to be scheduled, such as {Math101, Eng202,
CS303, etc.}.
Rooms: The set of all available rooms, such as {RoomA, RoomB, RoomC, etc.}.
Timeslots: The set of all possible timeslots, such as {Monday 9-10AM, Tuesday 11-
12PM, etc.}.
Teachers: The set of all teachers, such as {Mr. Smith, Ms. Johnson, Dr. Lee, etc.}.
Constraints:
1. Room Availability: Each room can be assigned only one class per timeslot.
o If class C1C1 is scheduled in room R1R1 at timeslot T1T1, no other class can be
scheduled in R1R1 at T1T1.
2. Teacher Availability: A teacher can teach only one class per timeslot.
o If teacher T1T1 is assigned to class C1C1 at timeslot T1T1, they cannot be
assigned to any other class at T1T1.
3. Classroom Capacity: The capacity of a classroom must be sufficient for the number of
students in the class.
o If class C1C1 has 30 students and room R1R1 has a capacity of 25, C1C1 cannot
be scheduled in R1R1.
4. Pre-requisite Courses: Certain classes need to be scheduled in a specific order.
o If class C2C2 is a prerequisite for class C3C3, then C2C2 must be scheduled
before C3C3.
5. Teacher Preferences: Teachers may have preferences or restrictions on when they can
teach.
o If teacher T1T1 prefers not to teach on Mondays, then no class should be
scheduled for T1T1 on Mondays.
6. Student Schedule Conflicts: Students enrolled in multiple classes should not have
scheduling conflicts.
o If a student is enrolled in both C1C1 and C2C2, these classes cannot be scheduled
at the same timeslot.
Example:
Let's consider a simplified version with three classes, two rooms, and two teachers over
three timeslots.
Variables:
Domains:
Constraints:
1. Room Availability: Each room can be used for only one class per timeslot.
2. Teacher Availability: Each teacher can teach only one class per timeslot.
3. Classroom Capacity: Assuming all rooms can accommodate any class for simplicity.
4. Teacher Preferences: Assume no preferences in this simplified example.
5. Student Schedule Conflicts: Ensure no overlapping classes for students.
Solution Approach:
Use a backtracking algorithm to assign classes to rooms, timeslots, and teachers while
respecting the constraints. If a conflict is found, backtrack and try a different assignment.
5. Write a Python program to solve a scheduling problem where three tasks must be
assigned to two people with no overlaps.
Answer 5: Here's a Python program to solve a scheduling problem where three tasks must be
assigned to two people with no overlaps. We'll use a simple backtracking approach to ensure
that no two tasks are assigned to the same person at the same time.
def is_valid_schedule(schedule):
# Check if any person has overlapping tasks (in this simple scenario, tasks can't
overlap)
if len(tasks) > 1:
return False
return True
if task_index == len(tasks):
return True
task = tasks[task_index]
schedule[person].append(task)
if is_valid_schedule(schedule):
return True
schedule[person].pop()
return False
if assign_tasks(schedule, 0):
print("Schedule found:")
print(f"{person}: {schedule[person]}")
else:
Explanation:
1. is_valid_schedule function: Ensures that no person has overlapping tasks. In this simple
scenario, each person can only have one task at a time.
2. assign_tasks function: Uses backtracking to assign tasks to people. It checks if the
current assignment is valid and recursively tries to assign the next task.
3. Base Case: When all tasks are assigned, the function returns True.
4. Backtracking: If an invalid assignment is found, the function backtracks by removing
the task and trying the next possible assignment.
You can run this code to find a valid schedule for the given tasks and people. This
approach ensures that each task is assigned without any overlaps for the individuals
involved.
6. Explain the differences between forward-checking and constraint propagation in
solving CSPs. Provide an example of each.
Forward-Checking:
Definition: Forward-checking is a technique used during the search process to reduce the
search space by checking the consistency of future variables. When a variable is assigned
a value, forward-checking looks ahead and checks if any of the unassigned neighboring
variables (those that are constrained by the current variable) are left with no valid values
due to the assignment. If any of these variables have no valid values left, the current
assignment is discarded.
How it works:
Example: Consider a simple CSP with two variables A and B, both having the domain
{1, 2, 3}. A constraint is that A ≠ B (i.e., A and B must have different values).
If at any step, B had no valid value left (e.g., if A was assigned a value such that B
couldn't be assigned any value), forward-checking would cause backtracking to try a
different value for A.
Advantages:
It checks only local constraints and doesn't propagate information across all variables.
May still lead to a large search space if the CSP has many variables.
Constraint Propagation:
Definition: Constraint propagation is a broader technique that reduces the search space
by enforcing global consistency over the CSP. It works by propagating constraints
throughout the network of variables. When a value is assigned to a variable, the effect of
this assignment is propagated to other related variables, reducing their possible values in
their domains.
How it works:
Example: Consider a CSP with three variables A, B, and C, all having the domain {1, 2,
3}. The constraints are:
A≠B
B≠C
A≠C
Constraint propagation continues until all variables are assigned valid values that satisfy
the constraints, or until no solution is possible.
Advantages:
Works globally across the CSP network, reducing more variables' domains and
potentially eliminating the need for backtracking.
Can be more effective in problems where there are many interdependencies between
variables.
Limitations:
Key Differences:
Both techniques improve the efficiency of solving CSPs, but constraint propagation is generally
more powerful as it considers global constraints across the network, while forward-checking is a
more localized technique that can still reduce search space but may not catch all inconsistencies
upfront.
Challenges
Consider a job scheduling problem where tasks must be assigned to workers while
satisfying various constraints (e.g., task dependencies, worker availability, skill
requirements). Formulating this as a CSP involves:
By addressing these challenges, you can effectively formulate and solve ML problems as
CSPs, leveraging the strengths of both approaches.
8. Modify the map coloring example to include additional regions and constraints.
What effect does this have on the solution complexity?
Answer 8: To modify the map coloring example by adding additional regions and
constraints, we'll expand the problem by introducing more regions and new adjacency
constraints. This will also provide an opportunity to analyze how this increases the
complexity of the solution space.
Let's add two more regions: "E" and "F", and introduce constraints where regions "E" and
"F" are adjacent to some of the other regions. This will increase the complexity of the
problem because more variables and constraints lead to a larger search space.
problem = Problem()
problem.addVariable("A", colors)
problem.addVariable("B", colors)
problem.addVariable("C", colors)
problem.addVariable("D", colors)
# Get solutions
solutions = problem.getSolutions()
return solutions
# Print solutions
print(map_coloring())
Explanation of Changes:
1. New Variables: We've added two new regions, "E" and "F", with the same color options
as the existing regions ("Red", "Green", "Blue").
2. New Constraints: We added constraints that the new regions cannot share the same color
as certain neighboring regions. Specifically:
o "A" and "E" cannot share the same color.
o "B" and "E" cannot share the same color.
o "D" and "F" cannot share the same color.
o "C" and "F" cannot share the same color.
Adding more regions and constraints will increase the complexity of the solution space in
the following ways:
Key Takeaways:
More regions and constraints lead to an increase in both the number of possible
assignments and the number of inter-variable dependencies.
This results in a larger and more complex search space, which can increase the
computation time.
Depending on the solver's efficiency (e.g., with techniques like forward-checking,
constraint propagation, or heuristics), the effect of this increased complexity may be
mitigated, but the problem will still inherently take longer to solve as the number of
variables and constraints grows.