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

基于NetworkX的有向交易网络递归查找节点入邻居的问询

解决NetworkX有向图递归追溯入邻居的问题

嘿,我懂你要做的事儿——从指定的银行账户节点出发,一层层往上找所有给它(或者给它的上游账户)转账的节点,直到挖完所有源头为止对吧?这在交易溯源这类场景里太常见了,我给你两种靠谱的实现方式:

方法1:递归实现(适合较浅的网络)

递归的思路特别直观:先找当前节点的所有直接转账方(入邻居),再对每个转账方递归找他们的上游,同时要记录已经处理过的节点,避免重复遍历甚至遇到循环时无限递归。

import networkx as nx

def recursive_find_in_neighbors(G, current_node, visited=None):
    # 初始化已访问集合
    if visited is None:
        visited = set()
    # 如果当前节点已经处理过,直接返回
    if current_node in visited:
        return visited
    # 标记当前节点为已处理
    visited.add(current_node)
    # 获取当前节点的所有入邻居(也就是给它转账的账户)
    in_neighbors = G.predecessors(current_node)
    # 递归遍历每个入邻居的上游
    for neighbor in in_neighbors:
        recursive_find_in_neighbors(G, neighbor, visited)
    return visited

# 示例使用
# 先模拟一个交易图:A转B,B转C,D转C,E转A,F转E
G = nx.DiGraph()
G.add_edges_from([("A", "B"), ("B", "C"), ("D", "C"), ("E", "A"), ("F", "E")])
start_node = "C"  # 我们要追溯所有给C(或其上游)转账的节点
all_source_nodes = recursive_find_in_neighbors(G, start_node)
print(f"所有向{start_node}(或其上游)转账的节点:{all_source_nodes}")
# 输出结果:{'C', 'B', 'A', 'E', 'F', 'D'}

代码细节说明:

  • G.predecessors(current_node):这比G.in_edges()更直接,它会直接返回当前节点的所有入邻居(转出方),不用手动从边里提取节点。
  • visited集合:核心作用是去重和防循环,比如如果存在A→B→A的闭环,不会让递归无限跑下去。
  • 最终返回的集合包含了起始节点本身,以及所有能通过转账路径到达它的节点。

方法2:迭代实现(适合深网络,避免栈溢出)

如果你的交易网络特别深,递归可能会触发Python的递归深度限制,这时候用迭代(栈/队列)的方式更稳妥:

def iterative_find_in_neighbors(G, start_node):
    visited = set()
    stack = [start_node]
    while stack:
        current_node = stack.pop()
        if current_node not in visited:
            visited.add(current_node)
            # 把当前节点的所有入邻居加入栈,继续追溯
            in_neighbors = G.predecessors(current_node)
            stack.extend(in_neighbors)
    return visited

# 示例使用
all_source_nodes = iterative_find_in_neighbors(G, start_node)
print(f"所有向{start_node}(或其上游)转账的节点:{all_source_nodes}")

代码细节说明:

  • 用栈模拟递归的过程,每次取出一个节点处理,再把它的上游加入栈。
  • 如果想按层级顺序遍历(先看直接给起始节点转账的,再看间接的),可以把栈改成队列(比如用collections.deque的popleft()),这样就是广度优先遍历(BFS),上面的栈实现是深度优先遍历(DFS)。

额外小提示

  • 如果你只想获取所有上游转账节点(不含起始节点本身),可以最后从结果里移除起始节点:all_source_nodes.remove(start_node)。
  • 要是需要追踪具体的转账路径(比如谁转给谁最终到起始节点),可以修改函数用字典记录每个节点的前驱,最后回溯就能得到完整路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:46:53