我有一个有481个节点和6817条边的有向图(权重是边出现的次数,否则它将是4百万条边)。该图如下所示:
我想查找大多数时候从最外面的节点进入图形中心的路径(也许总权重最高的路径?)。我已经计算出节点的特征向量中心性,并得出了前20个。这些节点是出现在中心的那些节点。我尝试过的:
d = g.successors(top20nodes[0])
h = g.subgraph(d)
在这种情况下,这是仅获得最终以该特征向量中心度最高的节点结束的节点的方法。但是,我不知道如何获得通向该节点的n个出现次数最多(权重最大)的路径。
理想情况下,我的最终结果将是这样,灰色节点只是为了表明我只对出现的n条路径感兴趣。在这种情况下,到中心的那四个红色路径:
我不一定要寻找确切的代码,我只是不知道如何从这里继续。有人知道如何实现这一目标吗?
答案 0 :(得分:1)
请注意,我的解决方案并不是完全理想的,在某些情况下,它可能会返回非最佳路径
我为您想到了一种算法。它有几个假设,因此并非最佳。但是它应该返回很好的结果。
首先,您应该定义图形中心(我将其保留在算法之外)。定义完后,应将所有中心节点仅替换为一个-主中心节点(不要忘记边缘)。之后,我的算法开始。
它从中心节点以定义的深度开始BFS树。这是主要的不完善部分:如果在两个节点之间有两条路径-长灯和短灯,则将选择短灯。我不确定这对您的图形是否至关重要,但看起来并不一定(图片不是很实用)。
在构建BFS树之后,它将总结BFS路径的所有异常并对其进行排序。然后,您只需选择前X条路径即可。
我希望它能帮助您解决问题:)
import networkx as nx
# Create graph
G = nx.DiGraph()
G.add_nodes_from([1,6,7,8,9,10,11,12,13,14,15,16,17])
G.add_weighted_edges_from([
(6,1,2),
(7,1,5),
(10,1,7),
(12,1,1),
(15,1,4),
(17,1,6),
(8,6,5),
(8,7,8),
(9,8,2),
(11,10,1),
(13,12,5),
(14,13,6),
(16,15,3),
(16,14,4),
(14,16,1),
])
# Get the BFS tree. 1 is the center, 100 is the BFS length. Note, that
# long lengths MAY waste a lot of computing time
B = nx.bfs_tree(G, 1, 100)
# Get our center
root = list(v for v, d in B.in_degree() if d == 0)[0]
# Get all leaves _in_BFS_tree
leaves = (v for v, d in B.out_degree() if d == 0)
# Get all paths
all_paths = [nx.shortest_path(B, root, l) for l in leaves]
# Get all sorted pairs [path, path_length]
result = sorted(
[
(
path, sum((G.edges[path[i+1], path[i]]['weight'])
for i in range(len(path) - 1))
)
for path in all_paths
],
key=lambda x: x[1],
reverse=True
)
result
[([1, 12, 13, 14], 12),
([1, 6, 8, 9], 9),
([1, 10, 11], 8),
([1, 15, 16], 7),
([1, 17], 6),
([1, 7], 5)]