ex2: init
This commit is contained in:
118
assignment2/csp.py
Normal file
118
assignment2/csp.py
Normal file
@@ -0,0 +1,118 @@
|
||||
from queue import Queue
|
||||
from typing import Any
|
||||
|
||||
|
||||
class CSP:
|
||||
def __init__(
|
||||
self,
|
||||
variables: list[str],
|
||||
domains: dict[str, set],
|
||||
edges: list[tuple[str, str]],
|
||||
):
|
||||
"""Constructs a CSP instance with the given variables, domains and edges.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
variables : list[str]
|
||||
The variables for the CSP
|
||||
domains : dict[str, set]
|
||||
The domains of the variables
|
||||
edges : list[tuple[str, str]]
|
||||
Pairs of variables that must not be assigned the same value
|
||||
"""
|
||||
self.variables = variables
|
||||
self.domains = domains
|
||||
|
||||
# Binary constraints as a dictionary mapping variable pairs to a set of value pairs.
|
||||
#
|
||||
# To check if variable1=value1, variable2=value2 is in violation of a binary constraint:
|
||||
# if (
|
||||
# (variable1, variable2) in self.binary_constraints and
|
||||
# (value1, value2) not in self.binary_constraints[(variable1, variable2)]
|
||||
# ) or (
|
||||
# (variable2, variable1) in self.binary_constraints and
|
||||
# (value1, value2) not in self.binary_constraints[(variable2, variable1)]
|
||||
# ):
|
||||
# Violates a binary constraint
|
||||
self.binary_constraints: dict[tuple[str, str], set] = {}
|
||||
for variable1, variable2 in edges:
|
||||
self.binary_constraints[(variable1, variable2)] = set()
|
||||
for value1 in self.domains[variable1]:
|
||||
for value2 in self.domains[variable2]:
|
||||
if value1 != value2:
|
||||
self.binary_constraints[(variable1, variable2)].add(
|
||||
(value1, value2)
|
||||
)
|
||||
self.binary_constraints[(variable1, variable2)].add(
|
||||
(value2, value1)
|
||||
)
|
||||
|
||||
def ac_3(self) -> bool:
|
||||
"""Performs AC-3 on the CSP.
|
||||
Meant to be run prior to calling backtracking_search() to reduce the search for some problems.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
False if a domain becomes empty, otherwise True
|
||||
"""
|
||||
# YOUR CODE HERE (and remove the assertion below)
|
||||
assert False, "Not implemented"
|
||||
|
||||
def _consistent(self, var, value, assignment) -> bool:
|
||||
for v in assignment:
|
||||
if (var, v) in self.binary_constraints.keys():
|
||||
if (value, assignment[v]) not in self.binary_constraints[(var, v)]:
|
||||
return False
|
||||
if (v, var) in self.binary_constraints.keys():
|
||||
if (value, assignment[v]) not in self.binary_constraints[(v, var)]:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _backtrack(self, assignment: dict[str, Any]) -> dict | None:
|
||||
if len(assignment) == len(self.variables):
|
||||
return assignment # base-case
|
||||
var = self._select_unassigned_variable(assignment)
|
||||
for value in self._order_domain_values(var, assignment):
|
||||
if not self._consistent(var, value, assignment):
|
||||
continue
|
||||
assignment[var] = value
|
||||
if result := self._backtrack(assignment):
|
||||
return result
|
||||
assignment.pop(var)
|
||||
return None # failure
|
||||
|
||||
def backtracking_search(self) -> None | dict[str, Any]:
|
||||
"""Performs backtracking search on the CSP.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None | dict[str, Any]
|
||||
A solution if any exists, otherwise None
|
||||
"""
|
||||
|
||||
def backtrack(assignment: dict[str, Any]):
|
||||
# YOUR CODE HERE (and remove the assertion below)
|
||||
assert False, "Not implemented"
|
||||
|
||||
return backtrack({})
|
||||
|
||||
|
||||
def alldiff(variables: list[str]) -> list[tuple[str, str]]:
|
||||
"""Returns a list of edges interconnecting all of the input variables
|
||||
|
||||
Parameters
|
||||
----------
|
||||
variables : list[str]
|
||||
The variables that all must be different
|
||||
|
||||
Returns
|
||||
-------
|
||||
list[tuple[str, str]]
|
||||
List of edges in the form (a, b)
|
||||
"""
|
||||
return [
|
||||
(variables[i], variables[j])
|
||||
for i in range(len(variables) - 1)
|
||||
for j in range(i + 1, len(variables))
|
||||
]
|
||||
Reference in New Issue
Block a user