@@ -74,10 +74,12 @@ def unassign(self, var, assignment):
74
74
75
75
def nconflicts (self , var , val , assignment ):
76
76
"""Return the number of conflicts var=val has with other variables."""
77
+
77
78
# Subclasses may implement this more efficiently
78
79
def conflict (var2 ):
79
80
return (var2 in assignment and
80
81
not self .constraints (var , val , var2 , assignment [var2 ]))
82
+
81
83
return count (conflict (v ) for v in self .neighbors [var ])
82
84
83
85
def display (self , assignment ):
@@ -153,6 +155,7 @@ def conflicted_vars(self, current):
153
155
return [var for var in self .variables
154
156
if self .nconflicts (var , current [var ], current ) > 0 ]
155
157
158
+
156
159
# ______________________________________________________________________________
157
160
# Constraint Propagation with AC-3
158
161
@@ -183,6 +186,7 @@ def revise(csp, Xi, Xj, removals):
183
186
revised = True
184
187
return revised
185
188
189
+
186
190
# ______________________________________________________________________________
187
191
# CSP Backtracking Search
188
192
@@ -208,6 +212,7 @@ def num_legal_values(csp, var, assignment):
208
212
return count (csp .nconflicts (var , val , assignment ) == 0
209
213
for val in csp .domains [var ])
210
214
215
+
211
216
# Value ordering
212
217
213
218
@@ -221,6 +226,7 @@ def lcv(var, assignment, csp):
221
226
return sorted (csp .choices (var ),
222
227
key = lambda val : csp .nconflicts (var , val , assignment ))
223
228
229
+
224
230
# Inference
225
231
226
232
@@ -245,6 +251,7 @@ def mac(csp, var, value, assignment, removals):
245
251
"""Maintain arc consistency."""
246
252
return AC3 (csp , {(X , var ) for X in csp .neighbors [var ]}, removals )
247
253
254
+
248
255
# The search, proper
249
256
250
257
@@ -274,6 +281,7 @@ def backtrack(assignment):
274
281
assert result is None or csp .goal_test (result )
275
282
return result
276
283
284
+
277
285
# ______________________________________________________________________________
278
286
# Min-conflicts hillclimbing search for CSPs
279
287
@@ -302,6 +310,7 @@ def min_conflicts_value(csp, var, current):
302
310
return argmin_random_tie (csp .domains [var ],
303
311
key = lambda val : csp .nconflicts (var , val , current ))
304
312
313
+
305
314
# ______________________________________________________________________________
306
315
307
316
@@ -356,7 +365,7 @@ def build_topological(node, parent, neighbors, visited, stack, parents):
356
365
visited [node ] = True
357
366
358
367
for n in neighbors [node ]:
359
- if (not visited [n ]):
368
+ if (not visited [n ]):
360
369
build_topological (n , node , neighbors , visited , stack , parents )
361
370
362
371
parents [node ] = parent
@@ -366,9 +375,9 @@ def build_topological(node, parent, neighbors, visited, stack, parents):
366
375
def make_arc_consistent (Xj , Xk , csp ):
367
376
"""Make arc between parent (Xj) and child (Xk) consistent under the csp's constraints,
368
377
by removing the possible values of Xj that cause inconsistencies."""
369
- #csp.curr_domains[Xj] = []
378
+ # csp.curr_domains[Xj] = []
370
379
for val1 in csp .domains [Xj ]:
371
- keep = False # Keep or remove val1
380
+ keep = False # Keep or remove val1
372
381
for val2 in csp .domains [Xk ]:
373
382
if csp .constraints (Xj , val1 , Xk , val2 ):
374
383
# Found a consistent assignment for val1, keep it
@@ -393,8 +402,9 @@ def assign_value(Xj, Xk, csp, assignment):
393
402
# No consistent assignment available
394
403
return None
395
404
405
+
396
406
# ______________________________________________________________________________
397
- # Map- Coloring Problems
407
+ # Map Coloring Problems
398
408
399
409
400
410
class UniversalDict :
@@ -446,27 +456,27 @@ def parse_neighbors(neighbors, variables=None):
446
456
return dic
447
457
448
458
449
- australia = MapColoringCSP (list ('RGB' ),
450
- 'SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: ' )
451
-
452
- usa = MapColoringCSP ( list ( 'RGBY' ),
453
- """WA: OR ID; OR: ID NV CA; CA: NV AZ; NV: ID UT AZ; ID: MT WY UT ;
454
- UT: WY CO AZ; MT: ND SD WY; WY: SD NE CO; CO: NE KA OK NM; NM: OK TX AZ ;
455
- ND: MN SD; SD: MN IA NE; NE: IA MO KA; KA: MO OK; OK: MO AR TX ;
456
- TX: AR LA; MN: WI IA; IA: WI IL MO; MO: IL KY TN AR; AR: MS TN LA ;
457
- LA: MS; WI: MI IL; IL: IN KY; IN: OH KY; MS: TN AL; AL: TN GA FL;
458
- MI: OH IN; OH: PA WV KY; KY: WV VA TN; TN: VA NC GA; GA: NC SC FL ;
459
- PA: NY NJ DE MD WV; WV: MD VA; VA : MD DC NC; NC: SC; NY: VT MA CT NJ ;
460
- NJ: DE; DE: MD; MD: DC; VT: NH MA; MA: NH RI CT; CT: RI; ME: NH;
461
- HI: ; AK: """ )
462
-
463
- france = MapColoringCSP ( list ( 'RGBY' ),
464
- """AL: LO FC; AQ: MP LI PC; AU: LI CE BO RA LR MP; BO: CE IF CA FC RA
465
- AU; BR: NB PL; CA: IF PI LO FC BO; CE: PL NB NH IF BO AU LI PC; FC: BO
466
- CA LO AL RA; IF: NH PI CA BO CE; LI: PC CE AU MP AQ; LO: CA AL FC; LR :
467
- MP AU RA PA; MP: AQ LI AU LR; NB : NH CE PL BR; NH: PI IF CE NB; NO :
468
- PI; PA: LR RA; PC: PL CE LI AQ; PI: NH NO CA IF; PL: BR NB CE PC; RA:
469
- AU BO FC PA LR""" )
459
+ australia_csp = MapColoringCSP (list ('RGB' ), """SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: """ )
460
+
461
+ usa_csp = MapColoringCSP ( list ( 'RGBY' ),
462
+ """WA: OR ID; OR: ID NV CA; CA: NV AZ; NV: ID UT AZ; ID: MT WY UT;
463
+ UT: WY CO AZ; MT: ND SD WY; WY: SD NE CO; CO: NE KA OK NM; NM: OK TX AZ ;
464
+ ND: MN SD; SD: MN IA NE; NE: IA MO KA; KA: MO OK; OK: MO AR TX ;
465
+ TX: AR LA; MN: WI IA; IA: WI IL MO; MO: IL KY TN AR; AR: MS TN LA ;
466
+ LA: MS; WI: MI IL; IL: IN KY; IN: OH KY; MS: TN AL; AL: TN GA FL ;
467
+ MI: OH IN; OH: PA WV KY; KY: WV VA TN; TN: VA NC GA; GA: NC SC FL;
468
+ PA: NY NJ DE MD WV; WV: MD VA; VA: MD DC NC; NC: SC; NY: VT MA CT NJ ;
469
+ NJ: DE; DE : MD; MD: DC; VT: NH MA; MA: NH RI CT; CT: RI; ME: NH ;
470
+ HI: ; AK: """ )
471
+
472
+ france_csp = MapColoringCSP ( list ( 'RGBY' ),
473
+ """AL: LO FC; AQ: MP LI PC; AU: LI CE BO RA LR MP; BO: CE IF CA FC RA
474
+ AU; BR: NB PL; CA: IF PI LO FC BO; CE: PL NB NH IF BO AU LI PC; FC: BO
475
+ CA LO AL RA; IF: NH PI CA BO CE; LI: PC CE AU MP AQ; LO: CA AL FC; LR:
476
+ MP AU RA PA; MP: AQ LI AU LR; NB: NH CE PL BR; NH: PI IF CE NB; NO :
477
+ PI; PA: LR RA; PC: PL CE LI AQ; PI : NH NO CA IF; PL: BR NB CE PC; RA :
478
+ AU BO FC PA LR""" )
479
+
470
480
471
481
# ______________________________________________________________________________
472
482
# n-Queens Problem
@@ -503,16 +513,16 @@ def __init__(self, n):
503
513
CSP .__init__ (self , list (range (n )), UniversalDict (list (range (n ))),
504
514
UniversalDict (list (range (n ))), queen_constraint )
505
515
506
- self .rows = [0 ]* n
507
- self .ups = [0 ]* ( 2 * n - 1 )
508
- self .downs = [0 ]* ( 2 * n - 1 )
516
+ self .rows = [0 ] * n
517
+ self .ups = [0 ] * ( 2 * n - 1 )
518
+ self .downs = [0 ] * ( 2 * n - 1 )
509
519
510
520
def nconflicts (self , var , val , assignment ):
511
521
"""The number of conflicts, as recorded with each assignment.
512
522
Count conflicts in row and in up, down diagonals. If there
513
523
is a queen there, it can't conflict with itself, so subtract 3."""
514
524
n = len (self .variables )
515
- c = self .rows [val ] + self .downs [var + val ] + self .ups [var - val + n - 1 ]
525
+ c = self .rows [val ] + self .downs [var + val ] + self .ups [var - val + n - 1 ]
516
526
if assignment .get (var , None ) == val :
517
527
c -= 3
518
528
return c
@@ -560,6 +570,7 @@ def display(self, assignment):
560
570
print (str (self .nconflicts (var , val , assignment )) + ch , end = ' ' )
561
571
print ()
562
572
573
+
563
574
# ______________________________________________________________________________
564
575
# Sudoku
565
576
@@ -646,9 +657,12 @@ def show_cell(cell): return str(assignment.get(cell, '.'))
646
657
647
658
def abut (lines1 , lines2 ): return list (
648
659
map (' | ' .join , list (zip (lines1 , lines2 ))))
660
+
649
661
print ('\n ------+-------+------\n ' .join (
650
662
'\n ' .join (reduce (
651
663
abut , map (show_box , brow ))) for brow in self .bgrid ))
664
+
665
+
652
666
# ______________________________________________________________________________
653
667
# The Zebra Puzzle
654
668
@@ -716,6 +730,7 @@ def zebra_constraint(A, a, B, b, recurse=0):
716
730
(A in Smokes and B in Smokes )):
717
731
return not same
718
732
raise Exception ('error' )
733
+
719
734
return CSP (variables , domains , neighbors , zebra_constraint )
720
735
721
736
0 commit comments