节点作为networkx中的格点
Posted
技术标签:
【中文标题】节点作为networkx中的格点【英文标题】:node as lattice sites in networkx 【发布时间】:2020-08-16 11:47:00 【问题描述】:我有树状图,看起来像带有树枝的长树干,每个树枝上都可以有“叶子”。它看起来基本上像(边缘没有图片):
o
oo
oo o
o o o
oooooooooooooooooooooooooo
o
o
树干的长度可以是任意的,每个垂直分支有十个节点,叶子最多只有一个节点。主干的每个节点最多有 4 条边。由于保证垂直的“叶子”永远不会重叠,我希望能够转换一个图形,使每个节点都在一个格子上,并获得一个形式的字典
dict = n1: (x1, y2), n2: (x2, y2), ...
ni
是节点 ID,(xi, yi)
是一对整数,表示格子上的位置。我尝试通过使用图G
的所有节点之间的最大距离获取主干来自己实现它:
nodeList = list(G.nodes)
dic =
for i, n1 in enumerate(nodeList):
for n2 in nodeList[i+1:]:
dic[(n1, n2)] = networkx.shortest_path(G,source=n1,target=n2)
dicLength = k: len(dic[k]) for k in dic
k = max(dicLength, key=dicLength.get)
trunk = dic[k]
然后我可以将树干设置为格子的 x 坐标:
lattice = k: (i, 0) for i, k in enumerate(trunk)
然后我尝试通过检查树干中的一个节点是否有两个以上的邻居来计算垂直分支,并从那里从一个节点迭代到另一个节点,但是在遇到叶子时我遇到了麻烦。此外,它不适用于大型树干。
networkx 有没有更简单的方法来做到这一点?
编辑:一个最小的例子是:
G = nx.path_graph(10)
G.add_edges_from([(3,11),(11,12),(12,13),(13,14),(13,15),(1,16)])
【问题讨论】:
【参考方案1】:我不完全确定通过添加图表的垂直分支所期望的输出,也许一个最小的示例将有助于澄清。但是,如果我对设置的理解正确,我建议您改为通过以下方式获取图表的 trunk。
您可以从找到图形的nx.eccentricity
开始,即给定节点与所有其他节点之间的最大距离。然后,通过找到它的最大值,或者换句话说,图的直径,我们可以将shortest_path
的搜索限制在图中的最大距离节点对(在单个主干的情况下,没有两端的分支是不必要的,找到extrema_cand
之间的最短路径就足够了):
ecc = nx.eccentricity(G)
diam = max(ecc.values())
extrema_cand = [node for node, length in ecc.items() if length==diam]
现在我们可以只在上述节点子集上寻找最短路径:
from itertools import combinations
trunk=[]
for nodes in combinations(extrema_cand, r=2):
trunk.append(nx.shortest_path(G,*nodes))
trunk = max(trunk, key=len)
通过过滤最后一行中的max
,我们确保节点不会出现在图表的相对两侧。虽然如前所述,如果有一个主干,extrema_cand
中唯一一对节点上的nx.shortest_path(G,*nodes)
就足够了。
然后对于分支,也许一个想法可以是遍历主干节点,并通过广度优先搜索发现 分支 和随后的叶子,忽略来自主干的路径 Co tianing 节点,或者已经遍历。
【讨论】:
我使用您以前的编辑之一来获取主干和分支的格点。当有一些叶子时,它们共享同一个站点。由于分支上的节点最多只能有一个叶子,因此我检查重复的网格站点,检查关联节点有多少邻居。如果它只有一个邻居,它是一片叶子,并且它的位置移动了一个,脚本就结束了。如果每个分支节点有多个叶子,它将无法正常工作,但我检查过它在我的情况下从未发生过。 很高兴它有帮助!我回滚了,因为我想到了更有效的做事方式,但没有太多时间……而且还因为它没有考虑这些情况。我很高兴您设法对其进行了调整以使其能够通过@Bulkilol 发挥作用以上是关于节点作为networkx中的格点的主要内容,如果未能解决你的问题,请参考以下文章