11"""CSP (Constraint Satisfaction Problems) problems and solvers. (Chapter 6)."""
22
3- from utils import *
3+ from utils import * # noqa
44import search
55
66from collections import defaultdict
77from functools import reduce
88
9+ import itertools
10+ import re
11+
912
1013class CSP (search .Problem ):
1114
@@ -44,7 +47,8 @@ class CSP(search.Problem):
4447 display(a) Print a human-readable representation
4548
4649 >>> search.depth_first_graph_search(australia)
47- <Node (('WA', 'B'), ('Q', 'B'), ('T', 'B'), ('V', 'B'), ('SA', 'G'), ('NT', 'R'), ('NSW', 'R'))>
50+ <Node (('WA', 'B'), ('Q', 'B'), ('T', 'B'), ('V', 'B'), ('SA', 'G'),
51+ ('NT', 'R'), ('NSW', 'R'))>
4852 """
4953
5054 def __init__ (self , vars , domains , neighbors , constraints ):
@@ -70,8 +74,8 @@ def nconflicts(self, var, val, assignment):
7074 "Return the number of conflicts var=val has with other variables."
7175 # Subclasses may implement this more efficiently
7276 def conflict (var2 ):
73- return (var2 in assignment
74- and not self .constraints (var , val , var2 , assignment [var2 ]))
77+ return (var2 in assignment and
78+ not self .constraints (var , val , var2 , assignment [var2 ]))
7579 return count_if (conflict , self .neighbors [var ])
7680
7781 def display (self , assignment ):
@@ -149,7 +153,7 @@ def conflicted_vars(self, current):
149153 return [var for var in self .vars
150154 if self .nconflicts (var , current [var ], current ) > 0 ]
151155
152- #______________________________________________________________________________
156+ # ______________________________________________________________________________
153157# Constraint Propagation with AC-3
154158
155159
@@ -180,7 +184,7 @@ def revise(csp, Xi, Xj, removals):
180184 revised = True
181185 return revised
182186
183- #______________________________________________________________________________
187+ # ______________________________________________________________________________
184188# CSP Backtracking Search
185189
186190# Variable ordering
@@ -251,17 +255,21 @@ def backtracking_search(csp,
251255 """[Fig. 6.5]
252256 >>> backtracking_search(australia) is not None
253257 True
254- >>> backtracking_search(australia, select_unassigned_variable=mrv) is not None
258+ >>> backtracking_search(australia,
259+ >>> select_unassigned_variable=mrv) is not None
255260 True
256- >>> backtracking_search(australia, order_domain_values=lcv) is not None
261+ >>> backtracking_search(australia,
262+ >>> order_domain_values=lcv) is not None
257263 True
258- >>> backtracking_search(australia, select_unassigned_variable=mrv, order_domain_values=lcv) is not None
264+ >>> backtracking_search(australia, select_unassigned_variable=mrv,
265+ >>> order_domain_values=lcv) is not None
259266 True
260267 >>> backtracking_search(australia, inference=forward_checking) is not None
261268 True
262269 >>> backtracking_search(australia, inference=mac) is not None
263270 True
264- >>> backtracking_search(usa, select_unassigned_variable=mrv, order_domain_values=lcv, inference=mac) is not None
271+ >>> backtracking_search(usa, select_unassigned_variable=mrv,
272+ >>> order_domain_values=lcv, inference=mac) is not None
265273 True
266274 """
267275
@@ -285,7 +293,7 @@ def backtrack(assignment):
285293 assert result is None or csp .goal_test (result )
286294 return result
287295
288- #______________________________________________________________________________
296+ # ______________________________________________________________________________
289297# Min-conflicts hillclimbing search for CSPs
290298
291299
@@ -313,12 +321,11 @@ def min_conflicts_value(csp, var, current):
313321 return argmin_random_tie (csp .domains [var ],
314322 lambda val : csp .nconflicts (var , val , current ))
315323
316- #______________________________________________________________________________
324+ # ______________________________________________________________________________
317325
318326
319327def tree_csp_solver (csp ):
320328 "[Fig. 6.11]"
321- n = len (csp .vars )
322329 assignment = {}
323330 root = csp .vars [0 ]
324331 X , parent = topological_sort (csp .vars , root )
@@ -339,7 +346,7 @@ def topological_sort(xs, x):
339346def make_arc_consistent (Xj , Xk , csp ):
340347 unimplemented ()
341348
342- #______________________________________________________________________________
349+ # ______________________________________________________________________________
343350# Map-Coloring Problems
344351
345352
@@ -417,7 +424,7 @@ def parse_neighbors(neighbors, vars=[]):
417424 PI; PA: LR RA; PC: PL CE LI AQ; PI: NH NO CA IF; PL: BR NB CE PC; RA:
418425 AU BO FC PA LR""" )
419426
420- #______________________________________________________________________________
427+ # ______________________________________________________________________________
421428# n-Queens Problem
422429
423430
@@ -507,17 +514,14 @@ def display(self, assignment):
507514 print (str (self .nconflicts (var , val , assignment ))+ ch , end = ' ' )
508515 print ()
509516
510- #______________________________________________________________________________
517+ # ______________________________________________________________________________
511518# Sudoku
512519
513- import itertools
514- import re
515-
516520
517521def flatten (seqs ): return sum (seqs , [])
518522
519- easy1 = '..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..'
520- harder1 = '4173698.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......'
523+ easy1 = '..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..' # noqa
524+ harder1 = '4173698.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......' # noqa
521525
522526_R3 = list (range (3 ))
523527_CELL = itertools .count ().__next__
@@ -531,6 +535,7 @@ def flatten(seqs): return sum(seqs, [])
531535 for v in unit :
532536 _NEIGHBORS [v ].update (unit - set ([v ]))
533537
538+
534539class Sudoku (CSP ):
535540
536541 """A Sudoku problem.
@@ -564,7 +569,8 @@ class Sudoku(CSP):
564569 8 1 4 | 2 5 3 | 7 6 9
565570 6 9 5 | 4 1 7 | 3 8 2
566571 >>> h = Sudoku(harder1)
567- >>> None != backtracking_search(h, select_unassigned_variable=mrv, inference=forward_checking)
572+ >>> None != backtracking_search(h, select_unassigned_variable=mrv,
573+ >>> inference=forward_checking)
568574 True
569575 """
570576 R3 = _R3
@@ -596,8 +602,9 @@ def show_cell(cell): return str(assignment.get(cell, '.'))
596602 def abut (lines1 , lines2 ): return list (
597603 map (' | ' .join , list (zip (lines1 , lines2 ))))
598604 print ('\n ------+-------+------\n ' .join (
599- '\n ' .join (reduce (abut , list (map (show_box , brow )))) for brow in self .bgrid ))
600- #______________________________________________________________________________
605+ '\n ' .join (reduce (
606+ abut , list (map (show_box , brow )))) for brow in self .bgrid ))
607+ # ______________________________________________________________________________
601608# The Zebra Puzzle
602609
603610
0 commit comments