【问题标题】:how to find all the paths on a tree (or multiple connected trees) in Python?如何在 Python 中找到一棵树(或多棵连接的树)上的所有路径?
【发布时间】:2020-07-31 09:17:20
【问题描述】:

我正在尝试使用 Python 从一棵或多棵相连的树中查找所有路径,例如,如果我的数据是:

a=pd.DataFrame({'predecessor':[1,2,1,4,5,5,5,7,7,10,11,11,8,8,8,14,14,14,16,16,21,16,15,15],
                'successor':[2,3,4,5,6,7,8,9,10,11,12,13,17,18,19,8,15,16,20,21,23,22,19,20]})

前任和后继意味着这两个数字是相连的。所以,我使用这些数据的树看起来像:

我想要的是所有的路径。一条路径类似于 [1,2,3] 或 [1,4,5,7,10,11,13]。我的真实数据很大,所以使用数据框来存储所有路径并不是一个好主意。也许列表列表(其中每个子列表都是完整路径)很有用。我希望结果是这样的:

[[1,2,3], 
 [1,4,5,7,10,11,13],
 [14,8,17],
 [14,16,21,23],
 ......]

那么,有谁能帮帮我吗?

【问题讨论】:

  • 您可以将数据帧转换为树,然后使用树遍历算法(BFS,DFS)来获取所有路径。也许 NetworkX(python 库)可以用来解决这个问题。

标签: python list search path tree


【解决方案1】:
import pandas as pd


a = pd.DataFrame({'predecessor': [1, 2, 1, 4, 5, 5, 5, 7, 7, 10, 11, 11, 8, 8, 8, 14, 14, 14, 16, 16, 21, 16, 15, 15],
                  'successor': [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 17, 18, 19, 8, 15, 16, 20, 21, 23, 22, 19, 20]})

# loop to store all the parent-child nodes and find out the root nodes and end nodes.
# A root node is a node only in 'predecessor' but not in 'successor'
# An end node is a node only in 'successor' but not in 'predecessor'
root_nodes = set()
end_nodes = set()
node_relations = {}
for i in range(len(a['predecessor'])):
    predecessor = a['predecessor'][i]
    successor = a['successor'][i]
    if predecessor not in node_relations.keys():
        node_relations[predecessor] = []
    node_relations[predecessor].append(successor)
    if predecessor not in a['successor'].values:
        root_nodes.add(predecessor)
    if successor not in a['predecessor'].values:
        end_nodes.add(successor)

# DFS + Memorization
def get_routes(root, memory):
    # when already in memory
    if root in memory.keys():
        return memory[root]
    # when it is the end node, return node itself as the routes
    if root in end_nodes:
        memory[root] = [[root]]
        return memory[root]
    # Loop all the successor routes and add root node before all of them
    memory[root] = []
    for successor in node_relations[root]:
        for route in get_routes(successor, memory):
            memory[root].append([root] + route)
    return memory[root]

# Loop from root nodes
memory = {}
result = []
for root in root_nodes:
    result.extend(get_routes(root, memory))

【讨论】:

  • 非常感谢!这几乎是我想要的!但是请让我再问一件事:我无法使用这种方式找到完整的路径。此代码可以找到一个前任的所有后继,而不是完整的路径。例如,[1,4,5,7,10,11,13] 在我的示例中是一个完整的路径。但是使用您的代码无法找到它。那么,您能告诉我更多关于这方面的信息吗?
  • 如果你打印result,你会发现它就在那里。
猜你喜欢
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
  • 2016-05-19
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
相关资源
最近更新 更多