本文目录导读:

我来详细介绍如何使用NetworkX进行子图同构检测。
基础子图同构检测
import networkx as nx
import matplotlib.pyplot as plt
# 创建目标图(大图)
G_target = nx.Graph()
G_target.add_edges_from([
(1, 2), (2, 3), (3, 4), (4, 1), # 正方形
(1, 5), (2, 6), (3, 7), (4, 8), # 向外连接
(5, 6), (6, 7), (7, 8), (8, 5) # 外圈
])
# 创建子图(要查找的模式)
G_pattern = nx.Graph()
G_pattern.add_edges_from([
('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'A') # 正方形
])
# 检测子图同构
matcher = nx.algorithms.isomorphism.GraphMatcher(G_target, G_pattern)
is_isomorphic = matcher.subgraph_is_isomorphic()
print(f"是否找到子图同构: {is_isomorphic}")
# 查找所有匹配
if is_isomorphic:
matches = list(matcher.subgraph_isomorphisms_iter())
print(f"找到 {len(matches)} 个匹配:")
for i, match in enumerate(matches[:3]): # 只显示前3个
print(f"匹配 {i+1}: {match}")
带节点属性匹配
# 创建带属性的图
G1 = nx.Graph()
G1.add_nodes_from([
(1, {'color': 'red', 'label': 'A'}),
(2, {'color': 'blue', 'label': 'B'}),
(3, {'color': 'red', 'label': 'A'}),
(4, {'color': 'green', 'label': 'C'})
])
G1.add_edges_from([(1, 2), (2, 3), (3, 4)])
G2 = nx.Graph()
G2.add_nodes_from([
('a', {'color': 'red', 'label': 'A'}),
('b', {'color': 'blue', 'label': 'B'}),
('c', {'color': 'red', 'label': 'A'}),
('d', {'color': 'green', 'label': 'C'})
])
G2.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd')])
# 自定义节点匹配函数
def node_match(n1_attrs, n2_attrs):
return n1_attrs['color'] == n2_attrs['color'] and n1_attrs['label'] == n2_attrs['label']
# 使用自定义匹配函数
matcher = nx.algorithms.isomorphism.GraphMatcher(
G1, G2, node_match=node_match
)
print(f"带属性匹配结果: {matcher.is_isomorphic()}")
if matcher.is_isomorphic():
print(f"节点映射: {list(matcher.mapping.items())}")
带边属性匹配
# 创建带边属性的图
G3 = nx.Graph()
G3.add_edge(1, 2, weight=1.0)
G3.add_edge(2, 3, weight=2.0)
G3.add_edge(3, 4, weight=1.0)
G4 = nx.Graph()
G4.add_edge('A', 'B', weight=1.0)
G4.add_edge('B', 'C', weight=2.0)
G4.add_edge('C', 'D', weight=1.0)
# 自定义边匹配函数
def edge_match(e1_attrs, e2_attrs):
return e1_attrs['weight'] == e2_attrs['weight']
matcher = nx.algorithms.isomorphism.GraphMatcher(
G3, G4, edge_match=edge_match
)
print(f"带边属性匹配结果: {matcher.is_isomorphic()}")
多子图匹配(查找所有形状)
# 创建复杂图
G_big = nx.Graph()
G_big.add_edges_from([
(0, 1), (1, 2), (2, 3), (3, 0), # 方形
(0, 4), (4, 5), (5, 0), # 三角形
(2, 6), (6, 7), (7, 2), # 另一个三角形
(3, 8), (8, 9), (9, 10), (10, 3) # 另一个方形
])
# 定义多个子图模式
patterns = {
'triangle': nx.Graph([('a', 'b'), ('b', 'c'), ('c', 'a')]),
'square': nx.Graph([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]),
'path_3': nx.Graph([('a', 'b'), ('b', 'c')])
}
# 查找每种模式
for name, pattern in patterns.items():
matcher = nx.algorithms.isomorphism.GraphMatcher(G_big, pattern)
count = sum(1 for _ in matcher.subgraph_isomorphisms_iter())
print(f"找到 {count} 个 {name} 形状")
可视化匹配结果
def visualize_subgraph_matches(G, pattern):
"""可视化子图匹配结果"""
matcher = nx.algorithms.isomorphism.GraphMatcher(G, pattern)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 绘制原图
pos = nx.spring_layout(G)
nx.draw(G, pos, ax=axes[0], with_labels=True, node_color='lightblue',
node_size=500, font_size=10)
axes[0].set_title("Original Graph")
# 绘制第一个匹配结果
match = next(matcher.subgraph_isomorphisms_iter(), None)
if match:
matched_nodes = list(match.keys())
pos_pattern = nx.spring_layout(pattern)
nx.draw(pattern, pos_pattern, ax=axes[1], with_labels=True,
node_color='lightgreen', node_size=500, font_size=10)
axes[1].set_title(f"Matched Pattern\n$\\rightarrow$ {matched_nodes}")
plt.tight_layout()
plt.show()
# 测试可视化
G_test = nx.Graph()
G_test.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 1), (1, 5), (2, 6)])
pattern_test = nx.Graph([('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'A')])
visualize_subgraph_matches(G_test, pattern_test)
实际应用:分子结构匹配
def find_molecular_patterns(molecule_graph, functional_groups):
"""
在分子图中查找功能团
参数:
- molecule_graph: 分子图
- functional_groups: 功能团字典 {name: graph}
"""
results = {}
for group_name, group_graph in functional_groups.items():
matcher = nx.algorithms.isomorphism.GraphMatcher(
molecule_graph, group_graph
)
matches = list(matcher.subgraph_isomorphisms_iter())
if matches:
results[group_name] = matches
print(f"找到 {group_name}: {len(matches)} 个")
return results
# 示例:查找苯环和羧基
benzene = nx.Graph([(1,2), (2,3), (3,4), (4,5), (5,6), (6,1)])
carboxyl = nx.Graph([(1,2), (2,3), (2,4)]) # C(=O)OH
molecule = nx.Graph()
molecule.add_edges_from([
(1,2), (2,3), (3,4), (4,5), (5,6), (6,1), # 苯环
(1,7), (7,8), (7,9), (7,10) # 取代基
])
functional_groups = {
'benzene': benzene,
'carboxyl': carboxyl
}
results = find_molecular_patterns(molecule, functional_groups)
性能优化技巧
def optimized_subgraph_matching(G_large, G_small, max_matches=10):
"""
优化的子图匹配,限制匹配数量
"""
matcher = nx.algorithms.isomorphism.GraphMatcher(G_large, G_small)
matches = []
for i, match in enumerate(matcher.subgraph_isomorphisms_iter()):
if i >= max_matches:
break
matches.append(match)
return matches
# 使用节点标签加速匹配
def fast_match_with_labels(G_target, G_pattern, node_labels):
"""
使用节点标签加速子图匹配
参数:
- node_labels: 字典 {node: label}
"""
def node_match_func(n1_attrs, n2_attrs):
return n1_attrs.get('label') == n2_attrs.get('label')
# 添加标签属性
nx.set_node_attributes(G_target, node_labels, 'label')
nx.set_node_attributes(G_pattern, node_labels, 'label')
matcher = nx.algorithms.isomorphism.GraphMatcher(
G_target, G_pattern, node_match=node_match_func
)
return list(matcher.subgraph_isomorphisms_iter())
- 基础API:
GraphMatcher和subgraph_isomorphisms_iter() - 自定义匹配: 通过
node_match和edge_match参数 - 性能考虑:
- 子图同构是NP完全问题
- 对于大图,考虑使用标签或属性加速
- 可以使用VF2算法(NetworkX默认使用)
- 应用场景:
- 分子结构匹配
- 社交网络模式检测
- 电路设计验证
- 知识图谱查询
通过这些示例,你可以根据具体需求选择合适的子图同构检测方法,对于大规模图,可能需要考虑使用专门的图数据库或优化算法。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播