document code
This commit is contained in:
@@ -58,9 +58,16 @@ class CSP:
|
||||
"""
|
||||
|
||||
def revise(csp, xi, xj) -> bool:
|
||||
"""Reduce the domain of xi if possible
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
Whether or not there was a domain reduction
|
||||
"""
|
||||
revised = False
|
||||
for x in set(csp.domains[xi]):
|
||||
if not any(
|
||||
if not any( # translation of algorithm's forall expression.
|
||||
[
|
||||
(x, y) in csp.binary_constraints[(xi, xj)]
|
||||
for y in csp.domains[xj]
|
||||
@@ -97,39 +104,57 @@ class CSP:
|
||||
A solution if any exists, otherwise None
|
||||
"""
|
||||
|
||||
def backtrack(csp, assignment: dict[str, Any]) -> dict | None:
|
||||
def backtrack(csp, assignment: dict[str, Any]) -> dict[str, Any] | None:
|
||||
"""The recursive engine of backtracking_search.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict[str, Any]
|
||||
The solution to bubble up
|
||||
None
|
||||
If current branch has no solution
|
||||
"""
|
||||
# this is read from stdout in sudoku.py. important to 2c).
|
||||
# yes, it couldv'e been done differently, but this is
|
||||
# quick and unintrusive.
|
||||
print("i have been called")
|
||||
if len(assignment) == len(csp.variables):
|
||||
if len(assignment) == len(csp.variables): # completion condition
|
||||
return assignment # base-case
|
||||
var = select_unassigned_variable(csp, assignment)
|
||||
for value in order_domain_values(csp, var, assignment):
|
||||
if not consistent(csp, var, value, assignment):
|
||||
continue
|
||||
continue # do nothing (skip iteration)
|
||||
assignment[var] = value
|
||||
if result := backtrack(csp, assignment):
|
||||
return result
|
||||
return result # return if not failure
|
||||
assignment.pop(var)
|
||||
print("i have failed")
|
||||
return None # failure
|
||||
|
||||
def consistent(csp, var, value, assignment) -> bool:
|
||||
"""Helper function to determine if an arc is consistent"""
|
||||
for v in assignment:
|
||||
if (var, v) in csp.binary_constraints.keys():
|
||||
if (value, assignment[v]) not in csp.binary_constraints[(var, v)]:
|
||||
return False
|
||||
if (v, var) in csp.binary_constraints.keys():
|
||||
if (v, var) in csp.binary_constraints.keys(): # bi-birectional
|
||||
if (value, assignment[v]) not in csp.binary_constraints[(v, var)]:
|
||||
return False
|
||||
return True
|
||||
|
||||
def select_unassigned_variable(csp, assignment) -> str:
|
||||
"""Helper function to find a variable that is yet to be assigned."""
|
||||
for v in csp.variables:
|
||||
if v not in assignment.keys():
|
||||
return v
|
||||
return "this shouldn't happen"
|
||||
|
||||
# choose least constrained value
|
||||
def order_domain_values(csp, var, assignment) -> list[Any]:
|
||||
"""Helper function to order the domain values.
|
||||
Orders on the least constrained value
|
||||
"""
|
||||
|
||||
# calculate a sorting key by counting constraints
|
||||
def compare(value) -> int:
|
||||
s = 0
|
||||
for neighbor in [
|
||||
@@ -145,7 +170,7 @@ class CSP:
|
||||
|
||||
return sorted(list(csp.domains[var]), key=compare)
|
||||
|
||||
return backtrack(self, {})
|
||||
return backtrack(self, {}) # start with no assignments
|
||||
|
||||
|
||||
def alldiff(variables: list[str]) -> list[tuple[str, str]]:
|
||||
|
||||
Reference in New Issue
Block a user