我有一个有602647个节点和982982个边的图。我想为Networkx图中的每个节点找到一阶和二阶联系人(即1跳联系人和2跳联系人)。
我构建了以下代码,它对于较小的图很好地工作,但从未完成对更大的图(如上面所示的图)的运行:
hop_1 = {}
hop_2 = {}
row_1 = {}
row_2 = {}
for u, g in G.nodes(data=True):
row_1.setdefault(u, nx.single_source_shortest_path_length(G, u, cutoff=1))
row_2.setdefault(u, nx.single_source_shortest_path_length(G, u, cutoff=2))
hop_1.update(row_1)
hop_2.update(row_2)一些注意事项:
是否有优化/改进此代码并完成运行的方法?
发布于 2019-09-07 10:59:15
我不知道networkx;但是,根据定义,一个可以到达的节点在<=2跳中也是可到达的,这就是single_source_shortest_path_length提供给您的。因此,您可以删除对single_source_shortest_path_length的第一个调用。
第二,你对字典的使用是非常奇怪的!为什么要使用setdefault而不是仅仅设置元素?而且,您正在使用update进行大量的复制,它不会做任何有用的事情,只会浪费时间。
我会做这样的事:
hop_1 = {}
hop_2 = {}
for u in G.nodes():
d1 = []
d2 = []
for v, n in nx.single_source_shortest_path_length(G, u, cutoff=2).items():
if n == 1:
d1.append(v)
elif n == 2:
d2.append(v)
hop_1[u] = d1
hop_2[u] = d2它在我的笔记本上花了大约一分钟的时间,上面有一个G_nm图形,由:
import networkx as nx
G = nx.gnm_random_graph(602647, 982982)请注意,tqdm很好地显示了长时间运行循环的进度,只需要import tqdm,并将外部for循环更改为:
for u in tqdm(G.nodes()):
...你会得到一个很好的酒吧报告进度
发布于 2019-09-07 15:50:45
要查找一阶和二阶邻居,可以使用函数all_neighbors()和node_boundary()。

hop1 = {}
hop2 = {}
for n in G.nodes():
neighbs1 = list(nx.all_neighbors(G, n))
hop1[n] = neighbs1
hop2[n] = list(nx.node_boundary(G, neighbs1 + [n])) + neighbs1
print(hop1)
# {0: [1, 2, 3], 1: [0, 2, 3], 2: [0, 1, 3, 4], 3: [0, 1, 2, 4], 4: [2, 3]}
print(hop2)
# {0: [4, 1, 2, 3], 1: [4, 0, 2, 3], 2: [0, 1, 3, 4], 3: [0, 1, 2, 4], 4: [0, 1, 2, 3]}https://stackoverflow.com/questions/57831743
复制相似问题