Это основано на ответе Алекса Мартелли, но оно должно работать. Это зависит от выражения source_node.children
, дающего итерабельность, которая будет перебирать все дочерние элементы source_node
. Он также полагается на то, что рабочий оператор ==
работает, чтобы сравнить два узла, чтобы убедиться, что они одинаковые. Использование is
может быть лучшим выбором. По-видимому, в используемой библиотеке синтаксис для получения итерации по всем детям равен graph[source_node]
, поэтому вам нужно будет соответствующим образом скорректировать код.
def allpaths(source_node, sink_node):
if source_node == sink_node: # Handle trivial case
return frozenset([(source_node,)])
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)
return result
Моя главная задача в том, что это делает глубина первого поиска, он будет тратить усилия, когда существует несколько путей от источника к узлу, что это внук, великий внук, и т.д. все источника, но не обязательно родитель раковины. Если бы он запомнил ответ для данного источника и узла-приемника, можно было бы избежать дополнительных усилий.
Вот пример того, как это будет работать:
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
Это также позволяет сохранить словарь запоминания между вызовами, так что если вам нужно вычислить ответ для нескольких источников и поглотителей узлов вы можете избежать много дополнительных усилий.
Гарантировано, что есть только один источник, из-за которого все изменения узла в конечном итоге возвращаются, и есть только одна раковина, к которой в конечном итоге приводят все цепочки узлов? Или источник и приемник большего графа, который распространяется на вещи, которые ведут от источника, или ведет в раковину? – Omnifarious
Хммм. Я точно не знаю, что вы подразумеваете под изменением узла, но есть конечные X различных источников и очень конечные Y различных поглотителей. – Tyler
@Tyler. И цели дается отличный источник, найдите все пути к отдельной раковине? – Omnifarious