减少 nedworkx 中图的节点/边数

我有一个带有许多 2 阶节点的图(从 Linestring 派生)。为了简化图形,我想将其简化为度数不等于 2 但仍包含相同整体连接的节点。您可以在下图中找到我的意思的示例。 所以如果在度数为 3 的两个节点之间有多个节点 mit degree=2,则应该删除中间的所有节点和边,并在两个 deg=3 节点之间建立一个与权重相同的连接。省略边的总和。

Example Picture of reduced Graph

adslfly 回答:减少 nedworkx 中图的节点/边数

您可以通过以下方式识别链:1) 归纳出仅包含度数为 2 的节点的子图,以及 2) 然后识别归纳子图中的各个组件。然后只需将每个链中的权重相加,并在连接到链端点的节点之间创建具有该权重的新边。

enter image description here

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,ax=ax2)
plt.show()
本文链接:https://www.f2er.com/47790.html

大家都在问