Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cb7a0b1

Browse files
antmarakisnorvig
authored andcommitted
Implemented Topological Sort (aimacode#401)
* Implement Topological Sort - Implemented topological_sort - Added auxiliary function build_topological - Updated call to topological_sort * Use defaultdict to build visited * Added test * Update csp.py Skip first item of iteration
1 parent c8e22e6 commit cb7a0b1

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

csp.py

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
class CSP(search.Problem):
1515
"""This class describes finite-domain Constraint Satisfaction Problems.
1616
A CSP is specified by the following inputs:
17-
variables A list of variables; each is atomic (e.g. int or string).
17+
variables A list of variables; each is atomic (e.g. int or string).
1818
domains A dict of {var:[possible_value, ...]} entries.
1919
neighbors A dict of {var:[var,...]} that for each variable lists
2020
the other variables that participate in constraints.
2121
constraints A function f(A, a, B, b) that returns true if neighbors
2222
A, B satisfy the constraint when they have values A=a, B=b
23+
2324
In the textbook and in most mathematical definitions, the
2425
constraints are specified as explicit pairs of allowable values,
2526
but the formulation here is easier to express and more compact for
@@ -29,7 +30,7 @@ class CSP(search.Problem):
2930
problem, that's all there is.
3031
3132
However, the class also supports data structures and methods that help you
32-
solve CSPs by calling a search function on the CSP. Methods and slots are
33+
solve CSPs by calling a search function on the CSP. Methods and slots are
3334
as follows, where the argument 'a' represents an assignment, which is a
3435
dict of {var:val} entries:
3536
assign(var, val, a) Assign a[var] = val; do other bookkeeping
@@ -307,8 +308,9 @@ def tree_csp_solver(csp):
307308
"""[Figure 6.11]"""
308309
assignment = {}
309310
root = csp.variables[0]
310-
X, parent = topological_sort(csp.variables, root)
311-
for Xj in reversed(X):
311+
root = 'NT'
312+
X, parent = topological_sort(csp, root)
313+
for Xj in reversed(X[1:]):
312314
if not make_arc_consistent(parent[Xj], Xj, csp):
313315
return None
314316
for Xi in X:
@@ -318,8 +320,43 @@ def tree_csp_solver(csp):
318320
return assignment
319321

320322

321-
def topological_sort(xs, x):
322-
raise NotImplementedError
323+
def topological_sort(X, root):
324+
"""Returns the topological sort of X starting from the root.
325+
326+
Input:
327+
X is a list with the nodes of the graph
328+
N is the dictionary with the neighbors of each node
329+
root denotes the root of the graph.
330+
331+
Output:
332+
stack is a list with the nodes topologically sorted
333+
parents is a dictionary pointing to each node's parent
334+
335+
Other:
336+
visited shows the state (visited - not visited) of nodes
337+
338+
"""
339+
nodes = X.variables
340+
neighbors = X.neighbors
341+
342+
visited = defaultdict(lambda: False)
343+
344+
stack = []
345+
parents = {}
346+
347+
build_topological(root, None, neighbors, visited, stack, parents)
348+
return stack, parents
349+
350+
def build_topological(node, parent, neighbors, visited, stack, parents):
351+
"""Builds the topological sort and the parents of each node in the graph"""
352+
visited[node] = True
353+
354+
for n in neighbors[node]:
355+
if(not visited[n]):
356+
build_topological(n, node, neighbors, visited, stack, parents)
357+
358+
parents[node] = parent
359+
stack.insert(0,node)
323360

324361

325362
def make_arc_consistent(Xj, Xk, csp):

tests/test_csp.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,18 @@ def test_universal_dict():
274274
def test_parse_neighbours():
275275
assert parse_neighbors('X: Y Z; Y: Z') == {'Y': ['X', 'Z'], 'X': ['Y', 'Z'], 'Z': ['X', 'Y']}
276276

277+
def test_topological_sort():
278+
root = 'NT'
279+
Sort, Parents = topological_sort(australia,root)
280+
281+
assert Sort == ['NT','SA','Q','NSW','V','WA']
282+
assert Parents['NT'] == None
283+
assert Parents['SA'] == 'NT'
284+
assert Parents['Q'] == 'SA'
285+
assert Parents['NSW'] == 'Q'
286+
assert Parents['V'] == 'NSW'
287+
assert Parents['WA'] == 'SA'
288+
277289

278290
if __name__ == "__main__":
279291
pytest.main()

0 commit comments

Comments
 (0)