This is based on Alex Martelli's answer, but it should work. It depends on the expression source_node.children giving an iterability that will iterate over all the children of source_node . It also relies on the working path for the == operator to compare two nodes to make sure they are the same. Using is may be a better choice. Apparently, in the library used, the syntax for iterating over all children is graph[source_node] , so you will need to adjust the code accordingly.
def allpaths(source_node, sink_node): if source_node == sink_node:
My main problem is that this makes the first search for depth, it will waste effort when there are several paths from source to node, that grandson, great-grandson, etc. the whole source, but not necessarily the parent, to sink. If he remembered the answer for this source and plunged into a node, additional efforts could be avoided.
Here is an example of how this will work:
def allpaths(source_node, sink_node, memo_dict = None): if memo_dict is None: # putting {}, or any other mutable object # as the default argument is wrong memo_dict = dict() if source_node == sink_node: # Don't memoize trivial case return frozenset([(source_node,)]) else: pair = (source_node, sink_node) if pair in memo_dict: # Is answer memoized already? return memo_dict[pair] else: result = set() for new_source in source_node.children: paths = allpaths(new_source, sink_node, memo_dict) for path in paths: path = (source_node,) + path result.add(path) result = frozenset(result) # Memoize answer memo_dict[(source_node, sink_node)] = result return result
It also allows you to save a dictionary of notes between calls, so if you need to calculate the answer for several nodes of the source and receiver, you can avoid a lot of effort.
source share