如何用NetworkX的is_isomorphic检查图的结构相等而非同构?
如何用NetworkX的
is_isomorphic判断图的节点边完全一致 问题背景
你给出的两个有向图拓扑结构同构(都是长度为3的链状结构),默认调用nx.is_isomorphic(G1, G2)会返回True,但你需要的是判断节点集合与边集合完全一致(仅允许边权重不同),由于G1和G2的终端节点分别是s4和s7,期望结果为False。
解决方案:用is_isomorphic实现严格匹配
可以通过指定node_match参数,强制is_isomorphic在判断同构时要求节点标识完全匹配,从而识别出两个图的差异。
方法1:利用节点属性匹配
给每个节点添加与自身标识一致的属性,再用categorical_node_match指定匹配该属性:
import networkx as nx from networkx.algorithms import isomorphism as iso G1, G2 = nx.DiGraph(), nx.DiGraph() G1.add_edges_from([("s1", "s2"), ("s2", "s3"), ("s3", "s4")]) G2.add_edges_from([("s1", "s2"), ("s2", "s3"), ("s3", "s7")]) # 给节点添加name属性,值为节点自身标识 for node in G1.nodes: G1.nodes[node]["name"] = node for node in G2.nodes: G2.nodes[node]["name"] = node # 创建匹配规则:要求name属性完全相等 node_matcher = iso.categorical_node_match("name", default=None) # 执行同构判断 print(nx.is_isomorphic(G1, G2, node_match=node_matcher)) # 输出:False
方法2:用DiGraphMatcher自定义匹配逻辑
直接通过DiGraphMatcher类定义节点匹配规则为节点标识相等,无需修改节点属性:
import networkx as nx from networkx.algorithms import isomorphism as iso G1, G2 = nx.DiGraph(), nx.DiGraph() G1.add_edges_from([("s1", "s2"), ("s2", "s3"), ("s3", "s4")]) G2.add_edges_from([("s1", "s2"), ("s2", "s3"), ("s3", "s7")]) # 节点匹配规则:两个节点的标识完全相等 def match_nodes(u, v): return u == v # 边匹配规则:无属性时直接返回True(若需匹配权重可自定义逻辑) def match_edges(e1_attr, e2_attr): return True # 初始化匹配器并判断同构 graph_matcher = iso.DiGraphMatcher(G1, G2, node_match=match_nodes, edge_match=match_edges) print(graph_matcher.is_isomorphic()) # 输出:False
更简便的替代方案
如果只是需要判断节点和边完全一致(不考虑拓扑同构,只看集合是否相等),直接使用nx.is_equal()即可,无需额外配置:
print(nx.is_equal(G1, G2)) # 输出:False
内容的提问来源于stack exchange,提问作者TripleH
相关产品推荐
相关产品推荐

