这是使用networkx提供的初始解决方案,它是一个优化的图计算库:
import numpy as np
import networkx as nx
I = np.array([0, 0, 1, 2, 2, 3])
J = np.array([1, 2, 0, 0, 3, 2])
I_, J_, K_ = [], [], [],
num_nodes = np.max(np.concatenate([I,J])) + 1
A = np.zeros((num_nodes, num_nodes))
A[I,J] = 1
print("Adjacency Matrix:")
print(A)
G = nx.from_numpy_matrix(A)
for i in range(num_nodes):
first_neighbors = list(G.neighbors(i))
for j in first_neighbors:
second_neighbor = list(G.neighbors(j))
second_neighbor_no_circle = list(filter(lambda node: node != i, second_neighbor))
num_second_neighbors = len(second_neighbor_no_circle)
if num_second_neighbors > 0:
I_.extend(num_second_neighbors * [i])
J_.extend(num_second_neighbors * [j])
K_.extend(second_neighbor_no_circle)
I_, J_, K_ = np.array(I_), np.array(J_), np.array(K_)
print("result:")
print(I_)
print(J_)
print(K_)
Adjacency Matrix:
[[0. 1. 1. 0.]
[1. 0. 0. 0.]
[1. 0. 0. 1.]
[0. 0. 1. 0.]]
result:
[0 1 2 3]
[2 0 0 2]
[3 2 1 0]
我对上面的代码使用了%%timeit
而没有打印语句来检查运行时间:49 µs ± 113 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
复杂度分析:
找到所有邻居的邻居本质上是在深度优先搜索算法中进行2步。这可能需要,取决于图的拓扑结构,最多O(|V| + |E|),其中|E|是图中的边数,|V|是顶点数。
据我所知,在一般图上没有更好的算法。
但是,如果您知道有关图的某些特殊属性,则可以更紧密地限制运行时间或者根据此知识改变当前算法。
例如,如果您知道所有顶点最多具有d条边,并且图具有一个连通组件,则此实现的界限变为O(2d),如果d << |E|,则相当不错。
如果您有任何问题,请告诉我。
networkx
或其他图形包。让包来处理你的效率问题。 - Prune