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

如何比较两个graphviz.Digraph对象?查找差异节点与边

比较两个Graphviz Digraph对象的方法

要找出两个Digraph的差异节点(仅在单图中存在的节点)和相似节点间的差异边,核心思路是提取两个图的节点、边元数据,再通过集合运算对比差异。以下是具体实现步骤和代码示例:

1. 提取图的核心数据

Graphviz的Digraph对象提供了直接访问节点、边的接口:

  • 节点:通过dot.nodes()获取所有节点名称,若需节点属性,可结合dot.node_attr(全局节点属性)和单个节点的自定义属性
  • 边:通过dot.edges()获取所有边的首尾节点对,若需边属性,可使用dot.get_edge(start, end)获取对应边的属性字典

2. 找出差异节点

通过集合运算快速定位节点差异:

  • 仅在dot1中存在的节点:set(dot1.nodes()) - set(dot2.nodes())
  • 仅在dot2中存在的节点:set(dot2.nodes()) - set(dot1.nodes())
  • 两个图共有的节点:set(dot1.nodes()) & set(dot2.nodes())

3. 找出相似节点间的差异边

针对共有的节点,进一步对比边的差异:

  1. 将每个图的边转换为可哈希的元组(比如(起点, 终点),若需比较属性则追加属性的键值对)
  2. 通过集合运算找出仅在单图中存在的边
  3. 过滤出仅涉及共有节点的边,即为相似节点间的差异边

代码示例

import graphviz

# 模拟用户的两个Digraph实例
dot1 = graphviz.Digraph(format='svg')
dot1.attr('node', shape='box')
dot1.node('add')
dot1.node('sub')
dot1.edge('add', 'sub')
dot1.edge('add', 'mul')

dot2 = graphviz.Digraph(format='svg')
dot2.attr('node', shape='box')
dot2.node('add')
dot2.node('mul')
dot2.edge('add', 'mul')
dot2.edge('mul', 'div')

# 提取节点集合
nodes1 = set(dot1.nodes())
nodes2 = set(dot2.nodes())

# 计算节点差异
only_in_dot1_nodes = nodes1 - nodes2
only_in_dot2_nodes = nodes2 - nodes1
common_nodes = nodes1 & nodes2

print(f"仅在dot1中的节点: {only_in_dot1_nodes}")
print(f"仅在dot2中的节点: {only_in_dot2_nodes}")
print(f"共有的节点: {common_nodes}")

# 提取边集合(可扩展为包含属性的元组)
def extract_edges(dot):
    edges = set()
    for start, end in dot.edges():
        # 若需比较边属性,替换为:(start, end, frozenset(dot.get_edge(start, end).items()))
        edges.add((start, end))
    return edges

edges1 = extract_edges(dot1)
edges2 = extract_edges(dot2)

# 计算共有节点间的边差异
only_in_dot1_edges = edges1 - edges2
only_in_dot2_edges = edges2 - edges1

common_node_edges_dot1 = {e for e in only_in_dot1_edges if e[0] in common_nodes and e[1] in common_nodes}
common_node_edges_dot2 = {e for e in only_in_dot2_edges if e[0] in common_nodes and e[1] in common_nodes}

print(f"共有节点间仅在dot1中的边: {common_node_edges_dot1}")
print(f"共有节点间仅在dot2中的边: {common_node_edges_dot2}")

补充说明

  • 如果需要对比节点/边的属性差异(比如节点的颜色、边的样式不同),可在提取数据时将属性信息加入元组(用frozenset存储属性键值对,保证可哈希),再进行集合运算
  • 若图结构复杂,也可将两个Digraph导出为DOT文件后用文本对比工具(如diff)分析,但程序化提取的方式更精准可控

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:27:24