Networkx优化,顶点的相邻集,收缩子图

时间:2019-02-06 18:31:14

标签: networkx graph-theory

我有一个函数,该函数返回G的子图S。我想创建一个图H,其中S中的每个连接分量都是H中的一个顶点,如果H之间有一条边,则两个顶点连接在H中G中的这些顶点集。

现在,我有一些可行的方法,但是创建H所需的时间是创建S所需时间的两倍。(根据cPro​​file,主要是由于node_boundary和connected_components函数的缘故)该过程将完成很多次,所以我希望能刮掉一小部分时间。我只真正需要H,所以我考虑创建不带中间函数的H,但是我无法使它与收缩一起使用。问题在于,应该从G中随机选择边缘,但是边缘收缩会改变H中顶点的名称,而翻译边缘的名称对我来说很困难。

创建S:

def sp(G):
    nodes = list(G.nodes)
    out = nx.Graph()
    for v in nodes:
        out.add_edge(v, random.choice(list(G.neighbors(v))))
    return out

从S创建H:

spr = sp(G)
H = nx.Graph()
bound = []

CC = list(nx.connected_components(spr))
for c in CC:
    H.add_node(CC.index(c))

for c in CC:
    bound.append(nx.node_boundary(G,c))
    for b in bound:
        inter = c.intersection(b)
        if len(inter) > 0:
            H.add_edge(CC.index(c), bound.index(b))

创建不带S的H:

nodes = list(G.nodes)
edges = []
out = G.copy()
for v in nodes:
    edges.append( (v, random.choice(list(G.neighbors(v)))) )

for e in edges:
    out = nx.contracted_edge(out, e)
return out

2 个答案:

答案 0 :(得分:1)

通常使用邻接矩阵更容易。这是一个肮脏的代码片段,它将在给定任意分区的情况下进行矩阵收缩。您应该能够由此构建图形。

顺便说一句,如果您真的只专注于连接的组件,那么您将看不到任何非对角线连接,并且可以大大简化此代码。我假设您的意思是分区和子图。

import numpy as np
import networkx as nx
from itertools import combinations_with_replacement

graph = nx.erdos_renyi_graph(n=40, p=0.05)
A = nx.to_numpy_matrix(graph)

cc_list = [list(cc) for cc in nx.connected_components(graph)]

def matrix_contraction(A, partition):
    contract_A = np.zeros((len(partition), len(partition)))

    for (ipart, ipartidx), (jpart, jpartidx) in combinations_with_replacement(enumerate(partition), 2):
        contract_A[ipart,jpart] = A[ipartidx][:, jpartidx].sum()
        contract_A[jpart,ipart] = A[jpartidx][:, ipartidx].sum()

    return contract_A


contracted_adj_matrix = matrix_contraction(A, cc_list)        




print(cc_list)
print(contracted_adj_matrix)

答案 1 :(得分:0)

我已经编辑了您的代码。尝试一下是否更快:

import networkx as nx
import random

G = nx.random_tree(1000)

def sp(graph, percent_of_edges):
    """returns a subgraph with a certain percentage of edges"""
    out = nx.Graph()
    edges = graph.edges
    sample = random.sample(edges, k = int(len(edges) * percent_of_edges/100))
    out.add_edges_from(sample)
    return out

# Creating H from S
spr = sp(G, 80)
H = nx.Graph()
bound = []

CC = list(nx.connected_components(spr))
H.add_nodes_from(range(len(CC)))

for c in CC:
    bound.append(nx.node_boundary(G, c))

for num1, c in enumerate(CC):
    for num2, b in enumerate(bound):
        if c.intersection(b):
            H.add_edge(num1, num2)