【问题标题】:python calculation error for graph with networkx带有networkx的图形的python计算错误
【发布时间】:2013-06-02 15:25:23
【问题描述】:

我根据数据挖掘收集的数据制作了一个巨大的图表。

我使用“networkx”制作图表,我想将巨大的图表更改为另一个图表。

对于每个节点,加权边的总和为1。

所以我写我的代码如下:

ng=nx.Graph()  
for n in g.nodes():  
    s=0.0  
    for nb in g.neighbors(n):  
         s=s+1.0/g[n][nb]['weight']  
    for nb in g.neighbors(n):  
        ng.add_edge(n,nb,weight=1.0/s/g[n][nb]['weight'])

通过如下代码检查结果后

for n in ng.neighbors('100002950636410'):
    print str(n) + ' : ' + str(ng[n]['100002950636410']['weight'])

邻居的总和不是 1,而且有很多边的“权重”为 1。

我有什么问题吗?我认为我的计算和代码是正确的,但如果问题是图形的大小,那我该怎么办?

【问题讨论】:

    标签: python networkx


    【解决方案1】:

    你的问题的问题

    我认为您的解决方案无法按照您尝试的方式工作。我先说明原因,然后在下面提出一个替代解决方案。

    考虑这段代码:

    import networkx as nx
    import matplotlib.pyplot as plt
    import random
    
    # Set up a graph with random edges and weights
    
    G = nx.barabasi_albert_graph(6, 2, seed= 3214562)
    for u,v in G.edges_iter():
        G[u][v]['weight'] = int(random.random() * 10)
    
    pos = nx.spring_layout(G)
    
    nx.draw(G, pos)
    nx.draw_networkx_edge_labels(G,pos)
    plt.show()
    

    它产生了这个数字:

    考虑节点 1。它有两条边,权重分别为 2 和 9。我们应该将权重分别调整为 2/11 和 9/11。

    接下来考虑节点 4。它现在有两条边,权重分别为 2/11 和 8。第一个权重是之前计算的固定,所以我们基本上将第二个权重调整为 8/(8+2/11)。

    我们现在有三个边的权重被调整和固定。我们现在对节点 0、3 和 5 重复此操作。到该过​​程结束时,节点 2 周围的所有边都已重新调整和固定,但它们的总和不会为 1,除非非常巧合。当然,在更大的图中,这个问题会出现得更快。

    解决方案

    我建议您为每个节点附加一个包含重新加权边缘字典的新数据属性,而不是重新加权边缘本身。这是演示的相关代码:

    for n in G.nodes_iter():
        total = sum([ attr['weight']
                      for u,v,attr in G.edges(n, data=True) ])
        total = float(total)
        weights = dict([(nb, G[n][nb]['weight']/total)
                        for nb in G.neighbors(n)])
        G[n]['adj_weights'] = weights
    
    # Print out the adjusted weights
    
    for n in G.nodes_iter():
        for nb,w in G[n]['adj_weights'].iteritems():
            w = int(w*1000)/1000.
            print '{} to {}: {}'.format(n, nb, w)
    

    这会产生:

    0 to 2: 0.272
    0 to 3: 0.727
    1 to 2: 0.818
    1 to 4: 0.181
    2 to 0: 0.081
    2 to 1: 0.243
    2 to 3: 0.243
    2 to 4: 0.216
    2 to 5: 0.216
    3 to 0: 0.363
    3 to 2: 0.409
    3 to 5: 0.227
    4 to 1: 0.2
    4 to 2: 0.8
    5 to 2: 0.615
    5 to 3: 0.384
    

    因此,到节点 0 的边总和为 1,例如,连接到节点 3 的边也是如此。但是从节点 0 看边 (0,3) 的权重为 0.727,从节点 3 看时为 0.363。

    我希望这能让你继续前进。

    【讨论】:

    • 这看起来是一个 惊人的 答案,但也许可以简单地说一下为什么重新加权边缘是不正确的方法? (可能已经解决了,只是我对问题域不够熟悉)。
    • 谢谢@Hannele。天真地重新权衡边缘会导致冲突,例如我的回答结论中所示。例如,当从节点 0 或节点 3 的角度进行归一化时,边 (0,3) 应该具有不同的权重。正如我在解决方案中演示的那样,当然可以对每个节点周围的边权重进行归一化只要权重属性为每个节点单独存储。另一种解决方案可能是在每条边上存储两个权重。
    猜你喜欢
    • 2015-08-27
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    相关资源
    最近更新 更多