减少networkx中图的节点/边数
Posted
技术标签:
【中文标题】减少networkx中图的节点/边数【英文标题】:Reduce number of nodes/edges of a Graph in nedworkx 【发布时间】:2021-09-30 14:24:54 【问题描述】:我有一个带有许多 2 级节点的 Graph(从 LineString 派生)。为了简化图表,我想将其简化为度数不等于 2 但仍包含相同整体连接的节点。你可以在下面的图片中找到我的意思的一个例子。 所以如果两个度数为3的节点之间有多个节点mit degree=2,则中间的所有节点和边都应该被删除,两个deg=3节点之间的单个连接应该与权重相同省略边的总和。
Example Picture of reduced Graph
【问题讨论】:
欢迎来到 SO!请告诉我们你到目前为止尝试了什么?你的代码呢? 【参考方案1】:您可以通过以下方式识别链:1) 诱导仅包含度数为 2 的节点的子图,以及 2) 然后识别诱导子图中的各个组件。然后,只需将每条链中的权重相加,并在连接到链端点的节点之间创建一条具有该权重的新边。
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
def contract(g):
"""
Contract chains of neighbouring vertices with degree 2 into a single edge.
Arguments:
----------
g -- networkx.Graph or networkx.DiGraph instance
Returns:
--------
h -- networkx.Graph or networkx.DiGraph instance
the contracted graph
"""
# create subgraph of all nodes with degree 2
is_chain = [node for node, degree in g.degree() if degree == 2]
chains = g.subgraph(is_chain)
# contract connected components (which should be chains of variable length) into single node
components = list(nx.components.connected_component_subgraphs(chains))
hyper_edges = []
for component in components:
end_points = [node for node, degree in component.degree() if degree < 2]
candidates = set([neighbor for node in end_points for neighbor in g.neighbors(node)])
connectors = candidates - set(list(component.nodes()))
hyper_edge = list(connectors)
weights = [component.get_edge_data(*edge)['weight'] for edge in component.edges()]
hyper_edges.append((hyper_edge, np.sum(weights)))
# initialise new graph with all other nodes
not_chain = [node for node in g.nodes() if not node in is_chain]
h = g.subgraph(not_chain).copy()
for hyper_edge, weight in hyper_edges:
h.add_edge(*hyper_edge, weight=weight)
return h
# create weighted graph
edges = np.random.randint(0, 20, size=(int(400*0.2), 2))
weights = np.random.rand(len(edges))
g = nx.Graph()
for edge, weight in zip(edges, weights):
g.add_edge(*edge, weight=weight)
h = nx.algorithms.minimum_spanning_tree(g)
# contract
i = contract(h)
# plot
pos = nx.spring_layout(h)
fig, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
nx.draw(h, pos=pos, ax=ax1)
nx.draw(i, pos=pos, ax=ax2)
plt.show()
【讨论】:
以上是关于减少networkx中图的节点/边数的主要内容,如果未能解决你的问题,请参考以下文章
networkx draw_network 在绘图周围绘制一个框架。我怎样才能防止这种情况?
Social Network Analysis的Centrality总结,以及networkx实现EigenCentrality,PageRank和KatzCentrality的对比