简体   繁体   中英

Networkx ignore nodes with certain values for attributes in shortest path

I want to calculate the shortest path in a graph from A and D, but only considering nodes with a given attribute. For example:

import pandas as pd
import networkx as nx

cols = ['node_a','node_b','travel_time','attribute']

data = [['A','B',3,'attribute1'],
        ['B','C',1,'attribute1'],
        [ 'C','D',7,'attribute1'],
         ['D','E',3,'attribute1'],
         ['E','F',2,'attribute1'],
         ['F','G',4,'attribute1'],
         ['A','L',4,'attribute2'],
         ['L','D',3,'attribute2']
         ]
edges = pd.DataFrame(data)
edges.columns = cols
G=nx.from_pandas_dataframe(edges,'node_a','node_b', ['travel_time','attribute'])

If i want to calculate the shortest path from A to D, the default method would be

nx.shortest_path(G,'A','D',weight='travel_time')

Which could give me ['A', 'L', 'D'] but if i only want to consider nodes with attribute1 , this wouldnt be the case. I cant see how to modify it though, is there a canonical way how instead of coding my own shortest path?

Thanks!

I don't know an out of the box solution, but you could make a subgraph from all nodes with the desired property (quick and dirty implementation):

edges = [(a,b) for (a,b,e) in G.edges(data=True) if e['attribute']=='attribute1']
nodes = []
for a,b in edges:
    nodes += [a,b]

nx.shortest_path(G.subgraph(nodes),'A','D',weight='travel_time')

Edit: @Joel rightly pointed out, this answer can give wrong results. To avoid those, you can query a duplicate of the graph that only has edges with the correct attributes:

H = G.copy()
edges_to_remove = [e for e in H.edges(data=True) if not e['attribute']=='attribute1']
H.remove_edges_from(edges_to_remove)
nx.shortest_path(H,'A','D',weight='travel_time')

Edit2 : Following up on this idea, I think one can make it a bit faster by removing and re-adding the edges from the original graph, without copying:

edges_to_remove = [e for e in G.edges(data=True) if not e['attribute']=='attribute1']
G.remove_edges_from(edges_to_remove)
nx.shortest_path(G,'A','D',weight='travel_time')
G.add_edges_from(edges_to_remove)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM