Johngoldenboy
Johngoldenboy

Reputation: 168

networkx MultiDiGraph access keys of edges making the shortest path

Using the networkx library, I define a MultDiGraph. I then calculate the shortest path between two given nodes. As my graph holds parallel edges, I would like to know the keys of the edges that make up the shortest path. Here's an example:

import networkx as nx

G = nx.MultiDiGraph()
G.add_edge('a', 'b', key=0, weight=1)
G.add_edge('a', 'b', key=1, weight=2)
G.add_edge('b', 'c', key=0, weight=1)

shortest_path = nx.shortest_path(G, source='a', target='c')
shortest_path_length = nx.shortest_path_length(G, source='a', target='c')
    
print(shortest_path)
print(shortest_path_length)

The result looks like this:

['a', 'b', 'c']
2

This is only correct if the shortest path between nodes 'a' and 'b' is via the key=0 (weight=1). I couldn't find anything in the docs that would allow me to retrieve the keys of the actual edges involved in the shortest path. How could I get to this information?

Upvotes: 0

Views: 859

Answers (2)

grazynaB
grazynaB

Reputation: 1

shortest_path = nx.shortest_path(G, source='a', target='c', weight='weigth')
node_edges = []
for p in nx.utils.pairwise(shortest_path):
    step1 = (G.get_edge_data(*p).items())
    step2 = min([d.get('weight') for k, d in step1])
    node_edges.extend( (k, d) for k, d in step1 if d.get('weight') == step2)
print(note_edges) 

The output is the edge data:

[(0, {'weight': 0}), (0, {'weight': 1})]

Firstly, nx.utils.pairwise(shortest_path) gets you tuples of node pairs from the list of nodes in the shortest_path, which you can use to get edge data. In step1 get all possible edges between the nodes.
In step2 find the min weight. In your example the sorting key for weight is easy, a simple min() would do, but a custom sorting based on a different edge attribute is also possible.
Lastly, find the edge where the edge attribute matches step2 and add it to the list of node_edges.
If anyone has a quicker, simpler idea, please let me know.

Upvotes: 0

DPM
DPM

Reputation: 935

Short answer is you cannot. Networkx does not have a functionality that returns the edges that comprise the shortest path. At most it can return the nodes that are in that shortest path.

A work around this is to assume that the edges in the shortest path are the shortest ones, therefore if two nodes in the path can form an edge with a key of either 1 or 0, assume it is the shortest one.

I have faced the same issue as you in: How does osmnx know which edges to plot in shortest path

I used a library called OSMNx and the feature I wanted needed to know which edges make the shortest path. The feature makes the same assumption as I have stated above (you can see the answer to the question)

Upvotes: 1

Related Questions