微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring_layout 不能与权重一起正常工作

如何解决Spring_layout 不能与权重一起正常工作

我正在尝试使用权重来定义节点之间的距离,但它不起作用。我什至尝试使用标准化值但没有成功。

import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()

raw_values = [(1,2,{'weight':70000000000}),(2,3,{'weight':700000}),(1,4,{'weight':1000000}),{'weight':50000000000})]

normalized_values = []
for l in list1:
    norm_value = np.log10(l[2]['weight'])
    normalized_values.append((l[0],l[1],{'weight': norm_value}))

G.add_edges_from(raw_values)

pos = nx.spring_layout(G)

nx.draw_networkx(G,pos)
edge_labels = nx.draw_networkx_edge_labels(G,pos)

plt.show()

这是我得到的结果,您可以看到节点非常接近,即使值非常不同:

enter image description here

解决方法

spring_layout 实现了 Fruchterman-Reingold 算法,该算法将图建模为节点相互排斥的系统。斥力被放置在连接节点之间的弹簧抵消。

networkx 中的实现存在一些问题,特别是排斥项。这在您的示例图中很明显,其中节点 3 永远不应位于中心,因为它是连接最少的节点。

然而,您的主要不满在于吸引力条款。基本上,您定义了克服任何排斥项的极强弹簧。结果,节点都聚集在一个点上。当 networkx 返回这些本质上是随机的位置时,这些位置会重新缩放到由 scalecenter 参数隐含的边界框。

您的问题可以通过按均值归一化权重而有所改善:

enter image description here

但是请注意,边 (1,4) 的小权重(即排斥力 > 1 和 4 之间的吸引力)阻止节点 1 和 4 靠近节点 2,即使 (2,4) 和(1,2) 非常大。换句话说,生成的布局也受到三角不等式的约束,没有归一化可能会改变这一点。因此,spring_layout 通常无法反映所有权重(权重是实际几何距离的树和图形除外)。

#!/usr/bin/env python
"""
https://stackoverflow.com/q/67116565/2912349
"""
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

if __name__ == '__main__':

    edge_weights = {
        (1,2) : 7_000_000_000,(2,3) : 700_000,(1,4) : 1_000_000,4) : 5_000_000_000,}

    G1 = nx.Graph([(source,target,{'weight' : w}) for (source,target),w in edge_weights.items()])
    pos1 = nx.spring_layout(G1)

    mean = np.mean(list(edge_weights.values()))
    G2 = nx.Graph([(source,{'weight' : w / mean}) for (source,w in edge_weights.items()])
    pos2 = nx.spring_layout(G2)

    fig,(ax1,ax2) = plt.subplots(1,2)
    nx.draw_networkx(G1,pos1,ax=ax1)
    nx.draw_networkx(G2,pos2,ax=ax2)
    ax1.set_title('Raw')
    ax2.set_title('Normalized')
    ax1.axis('off')
    ax2.axis('off')

    plt.show()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。