图操作(并、交、差、和)理解与代码问题求助
图操作(并集、交集等)的实现问题与修正
问题描述
我在理解和可视化图操作(union、intersection、difference、addition)时遇到了问题。尝试用np.union1d实现图的并集操作,并用reshape将输出的一维数组转为二维数组,代码能运行但结果不符合预期,希望有人解释问题并修正代码。
原代码如下:
import networkx as nx import numpy as np import matplotlib.pyplot as plt G = nx.Graph() plt.figure(figsize =(1, 5)) G.add_edges_from([(1, 2), (2, 3), (2, 3), (2, 4), (2, 5), (3, 4), (4, 5), (4, 6), (5, 7), (5, 8)]) # First Graph created plt.subplot(311) nx.draw_networkx(G) H = nx.Graph() H.add_edges_from([(5, 7), (7,5), (7, 4), (1, 2), (7, 8), (9, 10)]) # Second Graph created plt.subplot(312) nx.draw_networkx(H) ee = np.union1d(G,H) ee = np.reshape(G, (-1, 2)) # Third Graph Created I = nx.Graph() I.add_edges_from(ee) plt.subplot(313) nx.draw_networkx(I) plt.show()
问题分析
- 直接把NetworkX的
Graph对象传给np.union1d是错误的:np.union1d仅处理一维数组,无法识别Graph对象的边数据,不能直接对图对象执行数组操作。 np.reshape(G, (-1, 2))逻辑错误:Graph对象不是数组结构,无法直接做reshape转换,这行代码完全偏离了提取边的需求。- 额外说明:NetworkX的Graph会自动去重边,所以添加重复边(比如
(2,3)、(7,5))不会改变最终的图结构。
修正方案
要实现图的并集,有两种简单可靠的方式:
方式1:使用NetworkX内置的union函数
NetworkX本身提供了nx.union()函数,可直接合并两个图,自动处理节点和边的并集:
import networkx as nx import matplotlib.pyplot as plt G = nx.Graph() plt.figure(figsize=(8, 12)) G.add_edges_from([(1, 2), (2, 3), (2, 4), (2, 5), (3, 4), (4, 5), (4, 6), (5, 7), (5, 8)]) plt.subplot(311) nx.draw_networkx(G, with_labels=True) plt.title("图G") H = nx.Graph() H.add_edges_from([(5, 7), (7, 4), (1, 2), (7, 8), (9, 10)]) plt.subplot(312) nx.draw_networkx(H, with_labels=True) plt.title("图H") # 直接用内置函数合并两个图 I = nx.union(G, H) plt.subplot(313) nx.draw_networkx(I, with_labels=True) plt.title("G和H的并集") plt.tight_layout() plt.show()
方式2:提取边后用numpy处理(若坚持用numpy)
如果一定要用numpy实现边的并集,需先将两个图的边转换为数组,再做去重合并:
import networkx as nx import numpy as np import matplotlib.pyplot as plt G = nx.Graph() plt.figure(figsize=(8, 12)) G.add_edges_from([(1, 2), (2, 3), (2, 4), (2, 5), (3, 4), (4, 5), (4, 6), (5, 7), (5, 8)]) plt.subplot(311) nx.draw_networkx(G, with_labels=True) plt.title("图G") H = nx.Graph() H.add_edges_from([(5, 7), (7, 4), (1, 2), (7, 8), (9, 10)]) plt.subplot(312) nx.draw_networkx(H, with_labels=True) plt.title("图H") # 提取边并转为numpy数组 edges_G = np.array(list(G.edges())) edges_H = np.array(list(H.edges())) # 图的边是无序的,先对每条边排序,再合并去重 sorted_G = np.sort(edges_G, axis=1) sorted_H = np.sort(edges_H, axis=1) combined_edges = np.concatenate([sorted_G, sorted_H]) unique_edges = np.unique(combined_edges, axis=0) # 创建新图并添加处理后的边 I = nx.Graph() I.add_edges_from(unique_edges) plt.subplot(313) nx.draw_networkx(I, with_labels=True) plt.title("G和H的并集(numpy实现)") plt.tight_layout() plt.show()
额外说明
- 对于图的交集(intersection)、差集(difference)操作,NetworkX同样提供了
nx.intersection()、nx.difference()等内置函数,直接传入两个Graph对象即可,比手动用numpy处理更简洁可靠。 - 若用numpy处理边,必须注意图的边是无序的,需先对每条边的节点排序,避免把
(a,b)和(b,a)当成不同的边。
内容的提问来源于stack exchange,提问作者Dudu Mimi13
相关产品推荐
相关产品推荐

