Я думаю, что вы можете достичь этого, выполнив следующие шаги:
- используйте
neighbors
dict для хранения графика
- найти все точки ветвления, которые соседи считают> 2
- начать с каждой точки ветвления и использовать dfs , чтобы найти все пути
from collections import defaultdict
def find_branch_paths(exampleLineSegments):
# use dict to store the graph
neighbors = defaultdict(list)
for p1, p2 in exampleLineSegments:
neighbors[p1].append(p2)
neighbors[p2].append(p1)
# find all branch points
branch_points = [k for k, v in neighbors.items() if len(v) > 2]
res = []
def dfs(cur, prev, path):
# reach the leaf
if len(neighbors[cur]) == 1:
res.append(path)
return
for neighbor in neighbors[cur]:
if neighbor != prev:
dfs(neighbor, cur, path + [neighbor])
# start from all the branch points
for branch_point in branch_points:
dfs(branch_point, None, [branch_point])
return res
обновить версию iteration
для больших данных, что может привести к a recursion depth problem
:
def find_branch_paths(exampleLineSegments):
# use dict to store the graph
neighbors = defaultdict(list)
for p1, p2 in exampleLineSegments:
neighbors[p1].append(p2)
neighbors[p2].append(p1)
# find all branch points
branch_points = [k for k, v in neighbors.items() if len(v) > 2]
res = []
# iteration way to dfs
stack = [(bp, None, [bp]) for bp in branch_points]
while stack:
cur, prev, path = stack.pop()
if len(neighbors[cur]) == 1 or (prev and cur in branch_points):
res.append(path)
continue
for neighbor in neighbors[cur]:
if neighbor != prev:
stack.append((neighbor, cur, path + [neighbor]))
return res
тест и вывод:
print(find_branch_paths([(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (4, 7), (8, 7)]))
# output:
# [[4, 3, 2, 1], [4, 5, 6], [4, 7, 8]]
Надеюсь, что это поможет вам, и прокомментируйте, если у вас есть дополнительные вопросы. :)
ОБНОВЛЕНИЕ: если точек ветвления много, путь будет расти в геометрической прогрессии. Поэтому, если вам нужны только отдельные сегменты, вы можете закончить путь, когда встретите другую точку ветвления.
изменить эту строку
if len(neighbors[cur]) == 1:
до
if len(neighbors[cur]) == 1 or (prev and cur in branch_points):