2

According to the documentation an edge is uniquely defined by three parameters: u, v and k. SO even though u and v can be the same the parameter k differentiates between the edges

When I calculate the shortest path between two nodes I use nx.shortest_path. This gives me a list of the nodes that are in the shortest path.

Let's take an example, let's consider nodes 1 and 2. Now I calculate the shortest path between them and the result is the following:

[1, 4, 6, 7, 2]

If there is an egde u=4, v=6, k=0 and another u=4, v=6, k=1 how can I know which one is the one in the shortest path? How does osmnx know since it can plot the given shortest path?

Thank you in advance.

DPM
  • 845
  • 7
  • 33

2 Answers2

2

I'm the developer of OSMnx. It sounds like you're asking about its plot_graph_route function. In the case of parallel edges (i.e., multiple edges between some node u and some node v) along the shortest path, OSMnx picks the edge that is shorter in length. You can see exactly how it handles this here.

gboeing
  • 5,691
  • 2
  • 15
  • 41
  • I could not see a statement that deals with edges of the same length. I suppose it does not matter which is selected if the lengths are the same? – DPM Apr 18 '21 at 18:53
  • 1
    Correct. It will be up to the arbitrariness of which gets returned by the min function, if the values are equal. – gboeing Apr 19 '21 at 01:56
1

This appears to have two questions in it. I can answer the part involving networkx.

Graph:

To be a little pedantic (and because I'm imagining future people Googling this), this does depend on the type of graph you're working in. We'll start with a generic graph:

import networkx as nx

G = nx.path_graph(5)
G.add_edge(2, 8, weight=0.3)   # A
G.add_edge(2, 8, weight=0.6)   # B
G.add_edge(1, 8, weight=1.0)

for u, v, w in G.edges(data=True):
    print(u, v, k)

... and consider what happens if we switch the order of the lines marked A and B:

import networkx as nx

G = nx.path_graph(5)
G.add_edge(2, 8, weight=0.6)   # B
G.add_edge(2, 8, weight=0.3)   # A
G.add_edge(1, 8, weight=1.0)

for u, v, w in G.edges(data=True):
    print(u, v, k)

In both cases: the network will look the same:

Path graph showing six nodes connected by six edges

But the parameters of our network are different in the two cases:

# A first
0 1 {}
1 2 {}
1 8 {'weight': 1.0}
2 3 {}
2 8 {'weight': 0.6}
3 4 {}

and

# B first
0 1 {}
1 2 {}
1 8 {'weight': 1.0}
2 3 {}
2 8 {'weight': 0.3}
3 4 {}

So here: the answer is that u, v, and k are unique and the list returned by shortest_path will be unique.

MultiDiGraph:

I'm 90% sure this is the case the question wants to ask about. In a MultiDiGraph the nodes are still indexed by u, v, but there can be multiple weights k:

import networkx as nx

GM = nx.MultiDiGraph()
GM.add_edge(0, 2, weight=0.3)
GM.add_edge(0, 2, weight=0.15)
GM.add_edge(1, 2, weight=0.1)
GM.add_edge(0, 1, weight=0.1)
GM.add_edge(2, 3, weight=0.4)
GM.add_edge(2, 3, weight=0.5)

for u, v, w in GM.edges(data=True):
    print(u, v, w)

path = nx.shortest_path(GM, source=0, target=3, weight='weight')
print(path)
# [0, 2, 3]

The list returned by nx.shortest_path is ambiguous, but it's pretty straightforward to reconstruct the path of least weight:

for u, v in zip(path[0:], path[1:]):
    edge_data = GM.get_edge_data(u, v)
    min_weight = min([edge_data[edge]['weight'] for edge in edge_data])
    print(f"{u}---({min_weight})---{v}")

Result:

0---(0.15)---2
2---(0.4)---3
Alexander L. Hayes
  • 3,892
  • 4
  • 13
  • 34