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