Skip to content

Commit 7892bea

Browse files
dmeoliantmarakis
authored andcommitted
changed queue to set in AC3 (#1051)
* changed queue to set in AC3 Changed queue to set in AC3 (as in the pseudocode of the original algorithm) to reduce the number of consistency-check due to the redundancy of the same arcs in queue. For example, on the harder1 configuration of the Sudoku CSP the number consistency-check has been reduced from 40464 to 12562! * re-added test commented by mistake
1 parent 142e108 commit 7892bea

File tree

2 files changed

+19
-19
lines changed

2 files changed

+19
-19
lines changed

csp.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def conflicted_vars(self, current):
160160
def AC3(csp, queue=None, removals=None):
161161
"""[Figure 6.3]"""
162162
if queue is None:
163-
queue = [(Xi, Xk) for Xi in csp.variables for Xk in csp.neighbors[Xi]]
163+
queue = {(Xi, Xk) for Xi in csp.variables for Xk in csp.neighbors[Xi]}
164164
csp.support_pruning()
165165
while queue:
166166
(Xi, Xj) = queue.pop()
@@ -169,7 +169,7 @@ def AC3(csp, queue=None, removals=None):
169169
return False
170170
for Xk in csp.neighbors[Xi]:
171171
if Xk != Xj:
172-
queue.append((Xk, Xi))
172+
queue.add((Xk, Xi))
173173
return True
174174

175175

@@ -243,7 +243,7 @@ def forward_checking(csp, var, value, assignment, removals):
243243

244244
def mac(csp, var, value, assignment, removals):
245245
"""Maintain arc consistency."""
246-
return AC3(csp, [(X, var) for X in csp.neighbors[var]], removals)
246+
return AC3(csp, {(X, var) for X in csp.neighbors[var]}, removals)
247247

248248
# The search, proper
249249

@@ -374,7 +374,7 @@ def make_arc_consistent(Xj, Xk, csp):
374374
# Found a consistent assignment for val1, keep it
375375
keep = True
376376
break
377-
377+
378378
if not keep:
379379
# Remove val1
380380
csp.prune(Xj, val1, None)

tests/test_csp.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from csp import *
44
import random
55

6-
76
random.seed("aima-python")
87

98

@@ -174,7 +173,7 @@ def test_csp_conflicted_vars():
174173
def test_revise():
175174
neighbors = parse_neighbors('A: B; B: ')
176175
domains = {'A': [0], 'B': [4]}
177-
constraints = lambda X, x, Y, y: x % 2 == 0 and (x+y) == 4
176+
constraints = lambda X, x, Y, y: x % 2 == 0 and (x + y) == 4
178177

179178
csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)
180179
csp.support_pruning()
@@ -196,24 +195,24 @@ def test_revise():
196195
def test_AC3():
197196
neighbors = parse_neighbors('A: B; B: ')
198197
domains = {'A': [0, 1, 2, 3, 4], 'B': [0, 1, 2, 3, 4]}
199-
constraints = lambda X, x, Y, y: x % 2 == 0 and (x+y) == 4 and y % 2 != 0
198+
constraints = lambda X, x, Y, y: x % 2 == 0 and (x + y) == 4 and y % 2 != 0
200199
removals = []
201200

202201
csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)
203202

204203
assert AC3(csp, removals=removals) is False
205204

206-
constraints = lambda X, x, Y, y: (x % 2) == 0 and (x+y) == 4
205+
constraints = lambda X, x, Y, y: (x % 2) == 0 and (x + y) == 4
207206
removals = []
208207
csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)
209208

210209
assert AC3(csp, removals=removals) is True
211210
assert (removals == [('A', 1), ('A', 3), ('B', 1), ('B', 3)] or
212211
removals == [('B', 1), ('B', 3), ('A', 1), ('A', 3)])
213-
214-
domains = {'A': [ 2, 4], 'B': [ 3, 5]}
215-
constraints = lambda X, x, Y, y: int(x) > int (y)
216-
removals=[]
212+
213+
domains = {'A': [2, 4], 'B': [3, 5]}
214+
constraints = lambda X, x, Y, y: int(x) > int(y)
215+
removals = []
217216
csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)
218217

219218
assert AC3(csp, removals=removals)
@@ -247,7 +246,7 @@ def test_num_legal_values():
247246
def test_mrv():
248247
neighbors = parse_neighbors('A: B; B: C; C: ')
249248
domains = {'A': [0, 1, 2, 3, 4], 'B': [4], 'C': [0, 1, 2, 3, 4]}
250-
constraints = lambda X, x, Y, y: x % 2 == 0 and (x+y) == 4
249+
constraints = lambda X, x, Y, y: x % 2 == 0 and (x + y) == 4
251250
csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)
252251
assignment = {'A': 0}
253252

@@ -269,13 +268,13 @@ def test_mrv():
269268
def test_unordered_domain_values():
270269
map_coloring_test = MapColoringCSP(list('123'), 'A: B C; B: C; C: ')
271270
assignment = None
272-
assert unordered_domain_values('A', assignment, map_coloring_test) == ['1', '2', '3']
271+
assert unordered_domain_values('A', assignment, map_coloring_test) == ['1', '2', '3']
273272

274273

275274
def test_lcv():
276275
neighbors = parse_neighbors('A: B; B: C; C: ')
277276
domains = {'A': [0, 1, 2, 3, 4], 'B': [0, 1, 2, 3, 4, 5], 'C': [0, 1, 2, 3, 4]}
278-
constraints = lambda X, x, Y, y: x % 2 == 0 and (x+y) == 4
277+
constraints = lambda X, x, Y, y: x % 2 == 0 and (x + y) == 4
279278
csp = CSP(variables=None, domains=domains, neighbors=neighbors, constraints=constraints)
280279
assignment = {'A': 0}
281280

@@ -347,7 +346,7 @@ def test_min_conflicts():
347346
assert min_conflicts(france)
348347

349348
tests = [(usa, None)] * 3
350-
assert failure_test(min_conflicts, tests) >= 1/3
349+
assert failure_test(min_conflicts, tests) >= 1 / 3
351350

352351
australia_impossible = MapColoringCSP(list('RG'), 'SA: WA NT Q NSW V; NT: WA Q; NSW: Q V; T: ')
353352
assert min_conflicts(australia_impossible, 1000) is None
@@ -419,9 +418,9 @@ def test_parse_neighbours():
419418

420419
def test_topological_sort():
421420
root = 'NT'
422-
Sort, Parents = topological_sort(australia,root)
421+
Sort, Parents = topological_sort(australia, root)
423422

424-
assert Sort == ['NT','SA','Q','NSW','V','WA']
423+
assert Sort == ['NT', 'SA', 'Q', 'NSW', 'V', 'WA']
425424
assert Parents['NT'] == None
426425
assert Parents['SA'] == 'NT'
427426
assert Parents['Q'] == 'SA'
@@ -432,10 +431,11 @@ def test_topological_sort():
432431

433432
def test_tree_csp_solver():
434433
australia_small = MapColoringCSP(list('RB'),
435-
'NT: WA Q; NSW: Q V')
434+
'NT: WA Q; NSW: Q V')
436435
tcs = tree_csp_solver(australia_small)
437436
assert (tcs['NT'] == 'R' and tcs['WA'] == 'B' and tcs['Q'] == 'B' and tcs['NSW'] == 'R' and tcs['V'] == 'B') or \
438437
(tcs['NT'] == 'B' and tcs['WA'] == 'R' and tcs['Q'] == 'R' and tcs['NSW'] == 'B' and tcs['V'] == 'R')
439438

439+
440440
if __name__ == "__main__":
441441
pytest.main()

0 commit comments

Comments
 (0)