I'm using networkx to analyse a weighted, undirected graph and ran into a problem determining the barycenter. My graph is not connected, but made out of three components which are connected. Therefore, I use the function on each subgraph individually.
When I run nx.barycenter with the weights of the graphs it works, but if I run it with the shortest paths precalculated, it doesn't. In that case, I get the NetworkXNoPath: Input graph Graph with 6 nodes and 6 edges is disconnected, so every induced subgraph has infinite barycentricity. error.
So apparently this is related to the shortest_paths I'm giving the function.
The documentation says, I need All pairs shortest path lengths as a dictionary of dictionaries, but with the one I get from dict(nx.shortest_path_length(graph, weight = "weight")) it doesn't work.
Do I need to calculate it differently?
My code currently is:
import networkx as nx
def components(graph):
connected_comps = sorted(list(nx.connected_components(graph)), key=len, reverse=True)
return connected_comps
def subgraphs(graph):
subgraphs = []
connected_comps = components(graph)
for i, comp in enumerate(connected_comps):
subgraph = graph.subgraph(comp)
subgraphs.append(subgraph)
return subgraphs
graph = nx.Graph()
component1 = [387522, 7189, 3337, 5071]
component2 = [1, 2, 3, 4]
component3 = [2861, 3103, 7188, 387511, 387521, 387531]
graph.add_nodes_from(component1)
graph.add_nodes_from(component2)
graph.add_nodes_from(component3)
graph.add_edge(387522, 7189, weight = 0.55)
graph.add_edge(387522, 3337, weight = 0.55)
graph.add_edge(7189, 3337, weight = 0.86)
graph.add_edge(5071, 7189, weight = 0.72)
graph.add_edge(5071, 3337, weight = 0.72)
graph.add_edge(5071, 387522, weight = 0.72)
graph.add_edge(1, 2, weight = 0.78)
graph.add_edge(1, 3, weight = 0.78)
graph.add_edge(1, 4, weight = 0.78)
graph.add_edge(2, 3, weight = 0.78)
graph.add_edge(2, 4, weight = 0.78)
graph.add_edge(3, 4, weight = 0.78)
graph.add_edge(2861, 3103, weight = 0.78)
graph.add_edge(7188, 2861, weight = 0.86)
graph.add_edge(2861, 387511, weight = 0.86)
graph.add_edge(7188, 387521, weight = 0.86)
graph.add_edge(7188, 3103, weight = 0.86)
graph.add_edge(3103, 387531, weight = 0.86)
p = dict(nx.shortest_path_length(graph, weight = "weight"))
shortest_paths = {
'387522': {'387522': 0, '7189': 0.55, '3337': 0.55, '5071': 0.72},
'7189': {'7189': 0, '387522': 0.55, '3337': 0.86, '5071': 0.72},
'3337': {'3337': 0, '387522': 0.55, '7189': 0.86, '5071': 0.72},
'5071': {'5071': 0, '7189': 0.72, '3337': 0.72, '387522': 0.72},
'1': {'1': 0, '2': 0.78, '3': 0.78, '4': 0.78},
'2': {'2': 0, '1': 0.78, '3': 0.78, '4': 0.78},
'3': {'3': 0, '1': 0.78, '2': 0.78, '4': 0.78},
'4': {'4': 0, '1': 0.78, '2': 0.78, '3': 0.78},
'2861': {'2861': 0, '3103': 0.78, '7188': 0.86, '387511': 0.86, '387531': 1.64, '387521': 1.72},
'3103': {'3103': 0, '2861': 0.78, '7188': 0.86, '387531': 0.86, '387511': 1.64, '387521': 1.72},
'7188': {'7188': 0, '2861': 0.86, '387521': 0.86, '3103': 0.86, '387511': 1.72, '387531': 1.72},
'387511': {'387511': 0, '2861': 0.86, '3103': 1.64, '7188': 1.72, '387531': 2.5, '387521': 2.58},
'387521': {'387521': 0, '7188': 0.86, '2861': 1.72, '3103': 1.72, '387511': 2.58, '387531': 2.58},
'387531': {'387531': 0, '3103': 0.86, '2861': 1.64, '7188': 1.72, '387511': 2.5, '387521': 2.58}
}
def find_bary_center(graph, sp=None):
centers = []
for subgraph in subgraphs(graph):
if nx.is_connected(subgraph):
print("Connected", subgraph)
center = nx.barycenter(subgraph, sp=sp)
centers.append(center)
return centers
bary = find_bary_center(graph, p)
#print(p)
In this case, p has the same format as shortest_paths, but neither work. Both are a dictionary of dictionaries, so they seem like they should work, but they don't.
It appears that the shortest path dict is assumed to only contain nodes that are also in the graph being passed to
barycenter.