document code
This commit is contained in:
@@ -58,9 +58,16 @@ class CSP:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def revise(csp, xi, xj) -> bool:
|
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
|
revised = False
|
||||||
for x in set(csp.domains[xi]):
|
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)]
|
(x, y) in csp.binary_constraints[(xi, xj)]
|
||||||
for y in csp.domains[xj]
|
for y in csp.domains[xj]
|
||||||
@@ -97,39 +104,57 @@ class CSP:
|
|||||||
A solution if any exists, otherwise None
|
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")
|
print("i have been called")
|
||||||
if len(assignment) == len(csp.variables):
|
if len(assignment) == len(csp.variables): # completion condition
|
||||||
return assignment # base-case
|
return assignment # base-case
|
||||||
var = select_unassigned_variable(csp, assignment)
|
var = select_unassigned_variable(csp, assignment)
|
||||||
for value in order_domain_values(csp, var, assignment):
|
for value in order_domain_values(csp, var, assignment):
|
||||||
if not consistent(csp, var, value, assignment):
|
if not consistent(csp, var, value, assignment):
|
||||||
continue
|
continue # do nothing (skip iteration)
|
||||||
assignment[var] = value
|
assignment[var] = value
|
||||||
if result := backtrack(csp, assignment):
|
if result := backtrack(csp, assignment):
|
||||||
return result
|
return result # return if not failure
|
||||||
assignment.pop(var)
|
assignment.pop(var)
|
||||||
print("i have failed")
|
print("i have failed")
|
||||||
return None # failure
|
return None # failure
|
||||||
|
|
||||||
def consistent(csp, var, value, assignment) -> bool:
|
def consistent(csp, var, value, assignment) -> bool:
|
||||||
|
"""Helper function to determine if an arc is consistent"""
|
||||||
for v in assignment:
|
for v in assignment:
|
||||||
if (var, v) in csp.binary_constraints.keys():
|
if (var, v) in csp.binary_constraints.keys():
|
||||||
if (value, assignment[v]) not in csp.binary_constraints[(var, v)]:
|
if (value, assignment[v]) not in csp.binary_constraints[(var, v)]:
|
||||||
return False
|
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)]:
|
if (value, assignment[v]) not in csp.binary_constraints[(v, var)]:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def select_unassigned_variable(csp, assignment) -> str:
|
def select_unassigned_variable(csp, assignment) -> str:
|
||||||
|
"""Helper function to find a variable that is yet to be assigned."""
|
||||||
for v in csp.variables:
|
for v in csp.variables:
|
||||||
if v not in assignment.keys():
|
if v not in assignment.keys():
|
||||||
return v
|
return v
|
||||||
return "this shouldn't happen"
|
return "this shouldn't happen"
|
||||||
|
|
||||||
# choose least constrained value
|
|
||||||
def order_domain_values(csp, var, assignment) -> list[Any]:
|
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:
|
def compare(value) -> int:
|
||||||
s = 0
|
s = 0
|
||||||
for neighbor in [
|
for neighbor in [
|
||||||
@@ -145,7 +170,7 @@ class CSP:
|
|||||||
|
|
||||||
return sorted(list(csp.domains[var]), key=compare)
|
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]]:
|
def alldiff(variables: list[str]) -> list[tuple[str, str]]:
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user