networkx(Python) 中是否有一种计算可达性矩阵的捷径?
Is there a short way in networkx(Python) to calculate the reachability matrix?
假设我已经给出了一个有向图并且我想要一个numpy可达性矩阵是否存在路径,所以当且仅当存在从i到j的路径时R(i,j)=1;
networkx 具有函数has_path(G, source, target),但它仅针对特定的源节点和目标节点;因此,到目前为止我一直在这样做:
import networkx as nx
R=np.zeros((d,d))
for i in range(d):
for j in range(d):
if nx.has_path(G, i, j):
R[i,j]=1
有没有更好的方法来实现这个?
这是一个最小的实数示例:
import networkx as nx
import numpy as np
c=np.random.rand(4,4)
G=nx.DiGraph(c)
A=nx.minimum_spanning_arborescence(G)
adj=nx.to_numpy_matrix(A)
在这里我们可以看到这将是邻接矩阵而不是可达矩阵——以我的数字为例我会得到
adj=
matrix([[0. , 0. , 0. , 0. ],
[0. , 0. , 0.47971056, 0. ],
[0. , 0. , 0. , 0. ],
[0.16101491, 0.04779295, 0. , 0. ]])
所以有一条从 4 到 2 (adj(4,2)>0) 和从 2 到 3 (adj(2,3)>0) 的路径所以也有一条从 4 到 3 的路径但是 adj(4,3)=0
您可以使用 all_pairs_shortest_path_length:
import networkx as nx
import numpy as np
np.random.seed(42)
c = np.random.rand(4, 4)
G = nx.DiGraph(c)
length = dict(nx.all_pairs_shortest_path_length(G))
R = np.array([[length.get(m, {}).get(n, 0) > 0 for m in G.nodes] for n in G.nodes], dtype=np.int32)
print(R)
输出
[[1 1 1 1 1]
[0 1 1 1 1]
[0 0 1 1 1]
[0 0 0 1 1]
[0 0 0 0 1]]
一种方法是找到每个节点的所有后代,并将可到达的相应行设置为 1:
a = np.zeros((len(A.nodes()),)*2)
for node in A.nodes():
s = list(nx.descendants(A, node))
a[s, node] = 1
print(a)
array([[0., 0., 1., 0.],
[1., 0., 1., 0.],
[0., 0., 0., 0.],
[1., 1., 1., 0.]])
假设我已经给出了一个有向图并且我想要一个numpy可达性矩阵是否存在路径,所以当且仅当存在从i到j的路径时R(i,j)=1;
networkx 具有函数has_path(G, source, target),但它仅针对特定的源节点和目标节点;因此,到目前为止我一直在这样做:
import networkx as nx
R=np.zeros((d,d))
for i in range(d):
for j in range(d):
if nx.has_path(G, i, j):
R[i,j]=1
有没有更好的方法来实现这个?
这是一个最小的实数示例:
import networkx as nx
import numpy as np
c=np.random.rand(4,4)
G=nx.DiGraph(c)
A=nx.minimum_spanning_arborescence(G)
adj=nx.to_numpy_matrix(A)
在这里我们可以看到这将是邻接矩阵而不是可达矩阵——以我的数字为例我会得到
adj=
matrix([[0. , 0. , 0. , 0. ],
[0. , 0. , 0.47971056, 0. ],
[0. , 0. , 0. , 0. ],
[0.16101491, 0.04779295, 0. , 0. ]])
所以有一条从 4 到 2 (adj(4,2)>0) 和从 2 到 3 (adj(2,3)>0) 的路径所以也有一条从 4 到 3 的路径但是 adj(4,3)=0
您可以使用 all_pairs_shortest_path_length:
import networkx as nx
import numpy as np
np.random.seed(42)
c = np.random.rand(4, 4)
G = nx.DiGraph(c)
length = dict(nx.all_pairs_shortest_path_length(G))
R = np.array([[length.get(m, {}).get(n, 0) > 0 for m in G.nodes] for n in G.nodes], dtype=np.int32)
print(R)
输出
[[1 1 1 1 1]
[0 1 1 1 1]
[0 0 1 1 1]
[0 0 0 1 1]
[0 0 0 0 1]]
一种方法是找到每个节点的所有后代,并将可到达的相应行设置为 1:
a = np.zeros((len(A.nodes()),)*2)
for node in A.nodes():
s = list(nx.descendants(A, node))
a[s, node] = 1
print(a)
array([[0., 0., 1., 0.],
[1., 0., 1., 0.],
[0., 0., 0., 0.],
[1., 1., 1., 0.]])