@@ -257,7 +257,13 @@ def breadth_first(tree, children=iter, maxdepth=-1):
257257
258258
259259def edge_closure (tree , children = iter , maxdepth = - 1 , verbose = False ):
260- """Yield the edges of a graph in breadth-first order,
260+ """
261+ :param tree: the tree root
262+ :param children: a function taking as argument a tree node
263+ :param maxdepth: to limit the search depth
264+ :param verbose: to print warnings when cycles are discarded
265+
266+ Yield the edges of a graph in breadth-first order,
261267 discarding eventual cycles.
262268 The first argument should be the start node;
263269 children should be a function taking as argument a graph node
@@ -295,13 +301,13 @@ def edge_closure(tree, children=iter, maxdepth=-1, verbose=False):
295301def edges2dot (edges , shapes = None , attr = None ):
296302 """
297303 :param edges: the set (or list) of edges of a directed graph.
298-
299- :return dot_string: a representation of 'edges' as a string in the DOT
300- graph language, which can be converted to an image by the 'dot' program
301- from the Graphviz package, or nltk.parse.dependencygraph.dot2img(dot_string).
302-
303304 :param shapes: dictionary of strings that trigger a specified shape.
304305 :param attr: dictionary with global graph attributes
306+ :return: a representation of 'edges' as a string in the DOT graph language.
307+
308+ Returns dot_string: a representation of 'edges' as a string in the DOT
309+ graph language, which can be converted to an image by the 'dot' program
310+ from the Graphviz package, or nltk.parse.dependencygraph.dot2img(dot_string).
305311
306312 >>> import nltk
307313 >>> from nltk.util import edges2dot
@@ -337,8 +343,12 @@ def edges2dot(edges, shapes=None, attr=None):
337343
338344def unweighted_minimum_spanning_digraph (tree , children = iter , shapes = None , attr = None ):
339345 """
346+ :param tree: the tree root
347+ :param children: a function taking as argument a tree node
348+ :param shapes: dictionary of strings that trigger a specified shape.
349+ :param attr: dictionary with global graph attributes
340350
341- Build a Minimum Spanning Tree (MST) of an unweighted graph,
351+ Build a Minimum Spanning Tree (MST) of an unweighted graph,
342352 by traversing the nodes of a tree in breadth-first order,
343353 discarding eventual cycles.
344354
@@ -378,7 +388,15 @@ def unweighted_minimum_spanning_digraph(tree, children=iter, shapes=None, attr=N
378388
379389
380390def acyclic_breadth_first (tree , children = iter , maxdepth = - 1 , verbose = False ):
381- """Traverse the nodes of a tree in breadth-first order,
391+ """
392+ :param tree: the tree root
393+ :param children: a function taking as argument a tree node
394+ :param maxdepth: to limit the search depth
395+ :param verbose: to print warnings when cycles are discarded
396+ :return: the tree in breadth-first order
397+
398+ Adapted from breadth_first() above, to discard cycles.
399+ Traverse the nodes of a tree in breadth-first order,
382400 discarding eventual cycles.
383401
384402 The first argument should be the tree root;
@@ -389,32 +407,41 @@ def acyclic_breadth_first(tree, children=iter, maxdepth=-1, verbose=False):
389407 queue = deque ([(tree , 0 )])
390408 while queue :
391409 node , depth = queue .popleft ()
410+ if node in traversed :
411+ continue
392412 yield node
393413 traversed .add (node )
394414 if depth != maxdepth :
395415 try :
396416 for child in children (node ):
397417 if child not in traversed :
398418 queue .append ((child , depth + 1 ))
399- else :
400- if verbose :
401- warnings .warn (
402- "Discarded redundant search for {} at depth {}" .format (
403- child , depth + 1
404- ),
405- stacklevel = 2 ,
406- )
419+ elif verbose :
420+ warnings .warn (
421+ "Discarded redundant search for {} at depth {}" .format (
422+ child , depth + 1
423+ ),
424+ stacklevel = 2 ,
425+ )
407426 except TypeError :
408427 pass
409428
410429
411430def acyclic_depth_first (
412431 tree , children = iter , depth = - 1 , cut_mark = None , traversed = None , verbose = False
413432):
414- """Traverse the nodes of a tree in depth-first order,
433+ """
434+ :param tree: the tree root
435+ :param children: a function taking as argument a tree node
436+ :param depth: the maximum depth of the search
437+ :param cut_mark: the mark to add when cycles are truncated
438+ :param traversed: the set of traversed nodes
439+ :param verbose: to print warnings when cycles are discarded
440+ :return: the tree in depth-first order
441+
442+ Traverse the nodes of a tree in depth-first order,
415443 discarding eventual cycles within any branch,
416444 adding cut_mark (when specified) if cycles were truncated.
417-
418445 The first argument should be the tree root;
419446 children should be a function taking as argument a tree node
420447 and returning an iterator of the node's children.
@@ -476,7 +503,17 @@ def acyclic_depth_first(
476503def acyclic_branches_depth_first (
477504 tree , children = iter , depth = - 1 , cut_mark = None , traversed = None , verbose = False
478505):
479- """Traverse the nodes of a tree in depth-first order,
506+ """
507+ :param tree: the tree root
508+ :param children: a function taking as argument a tree node
509+ :param depth: the maximum depth of the search
510+ :param cut_mark: the mark to add when cycles are truncated
511+ :param traversed: the set of traversed nodes
512+ :param verbose: to print warnings when cycles are discarded
513+ :return: the tree in depth-first order
514+
515+ Adapted from acyclic_depth_first() above, to
516+ traverse the nodes of a tree in depth-first order,
480517 discarding eventual cycles within the same branch,
481518 but keep duplicate paths in different branches.
482519 Add cut_mark (when defined) if cycles were truncated.
@@ -548,15 +585,22 @@ def acyclic_branches_depth_first(
548585
549586
550587def acyclic_dic2tree (node , dic ):
551- """Convert acyclic dictionary 'dic', where the keys are nodes, and the
588+ """
589+ :param node: the root node
590+ :param dic: the dictionary of children
591+
592+ Convert acyclic dictionary 'dic', where the keys are nodes, and the
552593 values are lists of children, to output tree suitable for pprint(),
553594 starting at root 'node', with subtrees as nested lists."""
554595 return [node ] + [acyclic_dic2tree (child , dic ) for child in dic [node ]]
555596
556597
557598def unweighted_minimum_spanning_dict (tree , children = iter ):
558599 """
559- Output a dictionary representing a Minimum Spanning Tree (MST)
600+ :param tree: the tree root
601+ :param children: a function taking as argument a tree node
602+
603+ Output a dictionary representing a Minimum Spanning Tree (MST)
560604 of an unweighted graph, by traversing the nodes of a tree in
561605 breadth-first order, discarding eventual cycles.
562606
@@ -598,7 +642,10 @@ def unweighted_minimum_spanning_dict(tree, children=iter):
598642
599643def unweighted_minimum_spanning_tree (tree , children = iter ):
600644 """
601- Output a Minimum Spanning Tree (MST) of an unweighted graph,
645+ :param tree: the tree root
646+ :param children: a function taking as argument a tree node
647+
648+ Output a Minimum Spanning Tree (MST) of an unweighted graph,
602649 by traversing the nodes of a tree in breadth-first order,
603650 discarding eventual cycles.
604651
0 commit comments