【问题标题】:Python: Issues with Networkx Dijkstra algoPython:Networkx Dijkstra 算法的问题
【发布时间】:2014-06-20 22:02:54
【问题描述】:

我的目标是做与 here 发布的完全相同的事情。

我有一个如下所示的矩阵(DataFramedf):

community A   B   C   D
A         0   3   4   1
B         3   0   2   0
C         4   2   0   1
D         1   0   1   0 

这是一个对称的df,每个权重代表每个社区之间连接的权重或强度。如链接中所述,我想生成一个矩阵,显示所有节点(或社区)之间的最短距离。我先把上面的矩阵取反,设置G图网络:

G = nx.Graph()
commu = list(df.index)
for i in range(0,len(commu)):
    for j in range(0,len(commu)):
            if i == j:
                pass
            else:
                G.add_edge(str(i),str(j),weight=df.ix[df.index[i], df.columns[j]])

这给了我以下网络图: 边缘的不同颜色代表不同的权重。 (我更改了图表中数字的字母)

好的,到目前为止一切顺利。现在,我想要所有节点之间的最短距离。我正在考虑使用这个nx.dijkstra_shortest_path_length(G,source,target) 并遍历sourcetarget 的所有节点,并生成一个类似于上述链接的矩阵,其中包含矩阵每个单元格中所有节点的最短路径的所有值,但对于某些原因nx.dijkstra_shortest_path_length(G,source,target) 对我不起作用。 如果我执行nx.dijkstra_shortest_path_length(G,A,B) 或任何节点组合,我总是得到0。为什么?是否有一种有效的方法可以像使用Networkxnx.dijkstra 算法在链接中一样重现矩阵?

【问题讨论】:

    标签: python dijkstra networkx


    【解决方案1】:

    (不是答案,只是长评论)。如果

    In [65]: df.values
    Out[65]: 
    array([[0, 3, 4, 1],
           [3, 0, 2, 0],
           [4, 2, 0, 1],
           [1, 0, 1, 0]], dtype=int64)
    

    然后代替

    G = nx.Graph()
    commu = list(df.index)
    for i in range(0,len(commu)):
        for j in range(0,len(commu)):
                if i == j:
                    pass
                else:
                    G.add_edge(str(i),str(j),weight=df.ix[df.index[i], df.columns[j]])
    

    你可以用

    构造G
    In [66]: G = nx.from_numpy_matrix(df.values)
    
    In [67]: G.edges(data=True)
    Out[67]: 
    [(0, 1, {'weight': 3}),
     (0, 2, {'weight': 4}),
     (0, 3, {'weight': 1}),
     (1, 2, {'weight': 2}),
     (2, 3, {'weight': 1})]
    

    如果你想标记节点 ABCD 而不是 0123:

    In [68]: G = nx.relabel_nodes(G, dict(zip(range(4), 'ABCD')))
    
    In [69]: G.edges(data=True)
    Out[69]: 
    [('A', 'C', {'weight': 4}),
     ('A', 'B', {'weight': 3}),
     ('A', 'D', {'weight': 1}),
     ('C', 'B', {'weight': 2}),
     ('C', 'D', {'weight': 1})]
    

    【讨论】:

      【解决方案2】:

      您可以将 networkx.shortest_path(G) 与 weight='weight' 关键字一起使用。 例如

      In [1]: import networkx as nx
      
      In [2]: G = nx.Graph()
      
      In [3]: G.add_edge(1,2,weight=7)
      
      In [4]: G.add_edge(1,4,weight=3)
      
      In [5]: G.add_edge(2,3,weight=1)
      
      In [6]: G.add_edge(3,4,weight=100)
      
      In [7]: nx.adjacency_matrix(G).todense()
      Out[7]: 
      matrix([[  0,   7,   0,   3],
              [  7,   0,   1,   0],
              [  0,   1,   0, 100],
              [  3,   0, 100,   0]])
      
      In [8]: nx.shortest_path_length(G)
      Out[8]: 
      {1: {1: 0, 2: 1, 3: 2, 4: 1},
       2: {1: 1, 2: 0, 3: 1, 4: 2},
       3: {1: 2, 2: 1, 3: 0, 4: 1},
       4: {1: 1, 2: 2, 3: 1, 4: 0}}
      
      In [9]: nx.shortest_path_length(G,weight='weight')
      Out[9]: 
      {1: {1: 0, 2: 7, 3: 8, 4: 3},
       2: {1: 7, 2: 0, 3: 1, 4: 10},
       3: {1: 8, 2: 1, 3: 0, 4: 11},
       4: {1: 3, 2: 10, 3: 11, 4: 0}}
      
      In [10]: nx.utils.dict_to_numpy_array(nx.shortest_path_length(G,weight='weight'))
      Out[10]: 
      array([[  0.,   7.,   8.,   3.],
             [  7.,   0.,   1.,  10.],
             [  8.,   1.,   0.,  11.],
             [  3.,  10.,  11.,   0.]])
      

      【讨论】:

      • 所以nx.shortest_path_lengthnx.dijkstra_shortest_path_length之间没有区别?感谢您的帮助
      • 如果您将 weight=attribute 关键字与 nx.shortest_path_length 一起使用,它将运行 nx.dijkstra_shortest_path_length。默认值为 weight=None ,它执行非加权最短路径计算。
      猜你喜欢
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多