You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python执行时间优化:河流排放树路径列表全连通扩展方法咨询

生成河流排放树的所有连通路径并优化Python代码性能

首先明确问题:我们有一个表示河流排放树的字符串,格式为From;To的边集合,原始内容是:

From;To 1;2 2;3 5;4 3;4 4;-999 9;6 6;5 10;7 8;7 7;5

需要生成所有自上而下的连通路径(包括直接和间接连通的,比如1;3、1;4、8;4这类),同时要尽可能优化代码的执行效率。

核心思路:用记忆化遍历避免重复计算

直接对每个节点做深度优先搜索(DFS)会产生大量重复遍历(比如多个父节点指向同一个子节点时,该子节点的后代会被多次计算)。最优方案是先构建树的邻接表,再用**记忆化(缓存)**存储每个节点能到达的所有后代节点,每个节点仅计算一次,后续直接复用缓存结果。

具体实现步骤&优化代码

from functools import lru_cache

def generate_all_river_paths(raw_data):
    # 1. 解析原始数据,构建邻接表(父节点到直接子节点的映射)
    edges = raw_data.split()
    adjacency = {}
    # 跳过表头"From;To",处理每条边
    for edge in edges[1:]:
        from_node, to_node = edge.split(';')
        from_node = int(from_node)
        to_node = int(to_node)
        if to_node == -999:
            continue  # 终止节点无后续子节点,直接跳过
        if from_node not in adjacency:
            adjacency[from_node] = []
        adjacency[from_node].append(to_node)
    
    # 2. 记忆化函数:获取节点的所有后代(含间接连通的)
    @lru_cache(maxsize=None)
    def get_all_descendants(node):
        descendants = set()
        if node in adjacency:
            # 先添加直接子节点
            for child in adjacency[node]:
                descendants.add(child)
                # 递归添加子节点的所有后代
                descendants.update(get_all_descendants(child))
        return descendants
    
    # 3. 生成所有路径,用集合自动去重(效率远高于列表)
    all_paths = set()
    # 先加入原始的直接路径(排除指向终止节点的边)
    for edge in edges[1:]:
        if '-999' not in edge:
            all_paths.add(edge)
    # 加入所有间接连通的路径
    for from_node in adjacency:
        for to_node in get_all_descendants(from_node):
            all_paths.add(f"{from_node};{to_node}")
    
    return sorted(all_paths)

# 测试调用
raw_input = "From;To 1;2 2;3 5;4 3;4 4;-999 9;6 6;5 10;7 8;7 7;5"
result = generate_all_river_paths(raw_input)
print(result)

为什么这个方法效率高?

  • 邻接表构建:O(n)时间复杂度(n为原始边数),快速建立节点间的直接关联。
  • 记忆化DFS:每个节点仅被遍历一次,时间复杂度为O(V+E)(V为节点数,E为边数),彻底避免了重复递归的开销。
  • 集合去重:用集合存储路径,添加和判断存在性的时间复杂度均为O(1),比用列表做去重的O(n)效率提升显著。

额外优化建议

如果节点数量极大,手动用字典存储缓存结果(替代lru_cache)也是可行的,效果一致;若不需要结果排序,最后可直接返回列表形式的集合,省去排序的时间开销。

内容的提问来源于stack exchange,提问作者PDUY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:42:50