Вы ищете самые длинные пути в простом ориентированном графе, например:
"Hello" ------->\ /->"Beep bop Im a bot"->\
X X-->"Okay, what time is it?"
"Good morning"->/ \->"Hello, dear human"->/
Итак, вы ищете альтернативные пути в:
given = [ [0, "Hello"], [0, "Good morning"], [1, "Beep bop Im a bot"], [1, "Hello, dear human"], [0, "Okay, what time is it?" ] ]
Рекурсивный ответ здесь естествен :
- , если
given
пусто, у вас есть только пустой путь. - , если
given
не пусто, пусть head, tail
будет первым элементом given
и, соответственно, остальные элементы given
. У вас есть три возможности: - , если
tail
пусто, то единственный путь - [head.sentence]
; - , в противном случае, если
head.speaker != first element tail.speaker
, то вы получите [head.sentence] + path
для каждого пути в tail
; - иначе, если
head.speaker == first element tail.speaker
, то: a. привести пути в tail
(рекурсивный вызов) b. уберите первый элемент с tail
и l oop до 3. пока не окажетесь в случае 1. или 2.
Почему это работает? (эскиз демонстрации):
(I) У вас есть: given[0].speaker == path.speaker
на каждые path
в paths(given)
. Это правда, если given
имеет только один элемент. Иначе, вы дадите путь head.sentence + <something> == given[0].sentence + <something>
, или вы получите path
в paths(tail)
, где tail[0].speaker == head.speaker == given[0].speaker
- Вращение: вы получаете непосредственно элемент только в случае 1. или 2., когда за
head.sentence
следует paths(tail)
, а носитель первого элемента tail отличается от speker head
. Учитывая предложение (I), вы уверены, что за человеческим предложением всегда следует компьютерное предложение и наоборот. - Полнота: это верно для пустых путей, и поскольку вы пробуете любое возможное начало, потому что вы вызываете
paths
на каждом элементе, пока не произойдет вращение.
В python:
given = [ [0, "Hello"], [0, "Good morning"], [1, "Beep bop Im a bot"], [1, "Hello, dear human"], [0, "Okay, what time is it?" ] ]
def paths(L):
if L:
head, *tail = L
while tail and tail[0][0] == head[0]:
yield from paths(tail)
_, *tail = tail
for path in paths(tail):
yield [head[1]] + path
else:
yield []
print(list(paths(given)))
Вывод:
[['Good morning', 'Hello, dear human', 'Okay, what time is it?'], ['Good morning', 'Beep bop Im a bot', 'Okay, what time is it?'], ['Hello', 'Hello, dear human', 'Okay, what time is it?'], ['Hello', 'Beep bop Im a bot', 'Okay, what time is it?']]