1414class 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
325362def make_arc_consistent (Xj , Xk , csp ):
0 commit comments