2

Can someone confirm my finding the implementation of floyd_warshall_numpy method of networkx 2.5 is incorrect?

The code to reproduce is:

G = nx.balanced_tree(2, 3)
print(G.nodes())
print(nx.shortest_path(G, 2, 13))
print(nx.floyd_warshall_numpy(G, [2, 8, 13]))

My output is

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
[2, 6, 13]
[[ 0. inf inf]
 [inf  0. inf]
 [inf inf  0.]] 

I expected non Inf distances are computed for all [2, 8, 13] node pairs as the shortest path exists among all of them. It seems to me this implementation tries somehow to find path in a subgraph.

nx.floyd_warshall_numpy(G)

works correctly for all nodes. I find the documentation not intuitive here. https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.shortest_paths.dense.floyd_warshall_numpy.html#networkx.algorithms.shortest_paths.dense.floyd_warshall_numpy

Karel Marik
  • 811
  • 8
  • 13

3 Answers3

1

I've looked at the source code, and what's happening is that the algorithm only considers paths that involve the nodes you've given it.

So since there is no path between 2 and 8 that only includes the nodes 2, 8, and 13, it's returning inf.

I am not sure how best it should be fixed - whether it's better to update the documentation or the method.

Joel
  • 22,598
  • 6
  • 69
  • 93
0

I suspect your code meant to say print(nx.floyd_warshall_numpy(G, [2, 6, 13])) with a set of nodes [2, 6, 13] instead of [2, 8, 13]. Is that correct?

G = nx.balanced_tree(2, 3) 
print(G.nodes()) 
print(nx.shortest_path(G, 2, 13)) 
print(nx.floyd_warshall_numpy(G, [2, 6, 13]))                                                                         

Produces

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
[2, 6, 13]
[[0. 1. 2.]
 [1. 0. 1.]
 [2. 1. 0.]]
dschult
  • 184
  • 7
  • No. My goal is to get matrix of distances among nodes [2, 8, 13] within graph G, where G has nodes [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] – Karel Marik May 19 '21 at 16:40
0

I believe the problem is the explanation of nodelist in the documentation. Based on the documentation:
nodelist (list, optional) – The rows and columns are ordered by the nodes in nodelist. If nodelist is None then the ordering is produced by G.nodes(). But it does not mention the nodelist actually modifies the graph. It makes another graph using the nodes in nodelist.

Assume your Graph has 4 nodes [1,2,3,4] but you define the nodelist as [2,3,4]. When you read the documentation you think the function would calculate the distance matrix between nodes 2, 3, and 4 in the original graph. However, it seems it removes node 1 from the graph (technically changing the original graph) and then calculates the distance matrix between 2, 3, and 4. It can be problematic if node 1 is connecting nodes 2 and 3.

Sample Graph with 4 nodes

Dist_Mat=nx.algorithms.shortest_paths.dense.floyd_warshall_numpy(G,[1,2,3,4])  
print(Dist_Mat)  
[[0. 1. 1. 1.]
 [1. 0. 2. 2.]
 [1. 2. 0. 2.]
 [1. 2. 2. 0.]]

Dist_Mat=nx.algorithms.shortest_paths.dense.floyd_warshall_numpy(G,[2,3,4])  
print(Dist_Mat)
[[ 0. inf inf]
 [inf  0. inf]
 [inf inf  0.]]

please find the code below

import networkx as nx
import matplotlib.pyplot as plt
import nxviz as nv
G=nx.Graph()
G.add_node(1)
G.nodes[1]['N']=10
G.add_nodes_from([(2,{'N':20}),3,4])
G.add_edge(1,2)
G.edges[1,2]['E']=120
G.add_edges_from([(1,3,{'E':130}),(1,4)])
G.nodes()
pos = {0: (0, 0),
       1: (1, 0),
       2: (0, 1),
       3: (1, 1),
       4: (0.5, 2.0)}
print(G.nodes(data=True))
print(G.edges(data=True))
nx.draw(G, pos, with_labels=True, font_weight='bold')
FIG=nv.CircosPlot(G,node_size=1)
FIG.draw();plt.show()

Dist_Mat=nx.algorithms.shortest_paths.dense.floyd_warshall_numpy(G,[1, 2,3,4])
print(Dist_Mat)
Dist_Mat=nx.algorithms.shortest_paths.dense.floyd_warshall_numpy(G,[2,3,4])
print(Dist_Mat)
smv
  • 1
  • 2