python - Networkx 在图中查找不同最短路径之间的公共节点 - 是否有替代解决方案?
问题描述
我正在编写一个工具,用于识别网络中的节点,当给定一组两个或多个源和目的地遇到网络问题或延迟时,这些节点会导致延迟。我正在使用 networkx python 库来构建网络图。考虑这张图 -
a -- b -- c -- d
| |
e -- f
比如说,这些是面临网络问题的源和目标集。这意味着 a 和 d 之间的流量正在经历延迟,而 e 和 d 之间的流量正在经历延迟,依此类推。
| source | destination |
|--------|-------------|
| a | d |
| e | d |
| f | a |
- 我找到了这些源和目标对的最短路径。我在这两个列表之间取一个交集并检查这些设备上的错误。如果我有 100 对 (source, dest) 集,那么我将找到 100 个列表之间的公共节点,代表这两对之间的路径。
Shortest path host a to host d:
['a', 'b', 'c', 'd']
Shortest path host e to host d:
['e', 'b', 'c', 'd']
Shortest path host f to host a:
['f', 'c', 'b', 'a']
^^ 公共节点是“c”和“b”,因此请检查它们是否有错误。
- 我的问题是在networkx中是否有更好的方法来做到这一点,我可以在源和目标之间采用多条路径并找到一组共同的节点?我对网络/图论的了解非常有限,但这似乎是使用图解决的常见问题。
解决方案
我认为您正在寻找的是最大度数的节点,它们的每条边的平均权重最低。我们可以获得排序节点所需的信息,如下所示:
def avg_weight(graph, node):
all_edges = graph.edges(data=True)
edges = list(filter(lambda e: node in e, all_edges))
avg = 0
for e in edges:
avg += e[2]['weight'] / len(edges)
return avg
def weight_and_degree(graph):
degrees = dict(G.degree)
weights = dict(map(lambda n: (n, avg_weight(graph, n)), G.nodes))
return dict(map(lambda p: (p[0], (p[1], weights[p[0]])), degrees.items()))
现在这是一个(加权)图,它具有与您在上面指定的相同的属性。权重代表延迟时间。
import networkx as nx
G = nx.Graph()
G.add_edge('a','b', weight=0.1)
G.add_edge('b','c', weight=0.1)
G.add_edge('d','c', weight=0.1)
G.add_edge('b','e', weight=0.1)
G.add_edge('f','e', weight=0.3)
G.add_edge('f','c', weight=0.2)
如果我们在图上运行上述函数,我们可以像这样一次按度数和平均权重排序:
s = dict(sorted(weight_and_degree(G).items(), key=lambda x: (-x[1][0], x[1][1])))
print(' '.join(s.keys())) # b c e f a d
然后你可以根据你可用的资源查看这个列表的topn
结果,或者你可以修改代码只返回最大度数节点等。
参考:
推荐阅读
- telerik - Telerik RadGrid 滚动分页问题
- node.js - HTML to PDF with node-wkhtmltopdf 在 Digital Ocean Droplet 服务器上崩溃
- html - Rails 根据条件在 html 代码上包装 link_to
- javascript - Redux:连接函数中的对象解构?
- multithreading - Scala 原生线程和 GC 问题
- node.js - MongoDB,如何使用 $geoNear 检索给定范围内的文档
- python - 登录 Behave BDD 框架
- php - 是否可以从 SQL 触发器中的两个单独的表中减去两个列?
- r - 在闪亮的应用程序中上传文件并通过 textInput() 设置其名称
- apache-spark - Spark:如何在横向视图中包含空行爆炸