简体   繁体   English

Networkx:查找到Graph中多个节点之一的最短路径

[英]Networkx: Finding the shortest path to one of multiple nodes in Graph

I have a graph of different locations: 我有一个不同位置的图:

import networkx as nx

G = nx.Graph()
for edge in Edge.objects.all():
    G.add_edge(edge.from_location, edge.to_location, weight=edge.distance)

The locations (nodes) have different types (toilets, building entrances, etc.) I need to find the shortest way from some given location to any location of a specific type. 位置(节点)具有不同的类型(厕所,建筑物入口等),我需要找到从某个给定位置到特定类型的任何位置的最短路径。 (For example: Find the nearest entrance from a given node.) (例如:查找距给定节点最近的入口。)

Is there some method in the Networkx library to solve that without loops? Networkx库中是否有某种方法可以解决无循环问题? Something like: 就像是:

nx.shortest_path(
     G,
     source=start_location,
     target=[first_location, second_location],
     weight='weight'
)

The result will be the shortest path to either the first_location or the second_location, if both locations are of the same type. 如果两个位置属于同一类型,则结果将是到达first_location或second_location的最短路径。

And is there some method that also returns path length? 是否有一些方法也返回路径长度?

We will do it in three steps. 我们将分三步进行。

  • Step 1: Let's create a dummy graph to illustrate 步骤1:让我们创建一个虚拟图来说明
  • Step 2: Plot the graph and color nodes to indicate edge lengths and special node types (toilets, entrances etc.) 第2步:绘制图形和颜色节点,以指示边长和特殊节点类型(厕所,入口等)
  • Step 3: From any given node (source) calculate shortest path to all reachable nodes, then subset to the node types of interest and select path with the minimum length. 步骤3:从任何给定节点(源)计算到所有可达节点的最短路径,然后子集到感兴趣的节点类型并选择具有最小长度的路径。

The code below can definitely be optimized, but this might be easier to follow. 可以肯定地优化下面的代码,但这可能更容易遵循。

Step 1: Create the graph 步骤1:建立图表

edge_objects = [(1,2, 0.4), (1, 3, 1.7), (2, 4, 1.2), (3, 4, 0.3), (4 , 5, 1.9), 
(4 ,6, 0.6), (1,7, 0.4), (3,5, 1.7), (2, 6, 1.2), (6, 7, 0.3), 
(6, 8, 1.9), (8,9, 0.6)]

toilets = [5,9] # Mark two nodes (5 & 9) to be toilets
entrances = [2,7] # Mark two nodes (2 & 7) to be Entrances
common_nodes = [1,3,4,6,8] #all the other nodes

node_types = [(9, 'toilet'), (5, 'toilet'),
              (7, 'entrance'), (2, 'entrance')]

#create the networkx Graph with node types and specifying edge distances
G = nx.Graph()

for n,typ in node_types:
    G.add_node(n, type=typ) #add each node to the graph

for from_loc, to_loc, dist in edge_objects:
    G.add_edge(from_loc, to_loc, distance=dist) #add all the edges   

Step 2: Draw the graph 步骤2:绘制图形

#Draw the graph (optional step)
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True)
edge_labels = nx.get_edge_attributes(G,'distance')
nx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels)
nx.draw_networkx_nodes(G, pos, nodelist=toilets, node_color='b')
nx.draw_networkx_nodes(G, pos, nodelist=entrances, node_color='g')
nx.draw_networkx_nodes(G, pos, nodelist=common_nodes, node_color='r')
plt.show()

在此处输入图片说明

Step 3: create small functions to find the shortest path to node type 步骤3:创建小函数以找到节点类型的最短路径

def subset_typeofnode(G, typestr):
    '''return those nodes in graph G that match type = typestr.'''
    return [name for name, d in G.nodes(data=True) 
            if 'type' in d and (d['type'] ==typestr)]

#All computations happen in this function
def find_nearest(typeofnode, fromnode):

    #Calculate the length of paths from fromnode to all other nodes
    lengths=nx.single_source_dijkstra_path_length(G, fromnode, weight='distance')
    paths = nx.single_source_dijkstra_path(G, fromnode)

    #We are only interested in a particular type of node
    subnodes = subset_typeofnode(G, typeofnode)
    subdict = {k: v for k, v in lengths.items() if k in subnodes}

    #return the smallest of all lengths to get to typeofnode
    if subdict: #dict of shortest paths to all entrances/toilets
        nearest =  min(subdict, key=subdict.get) #shortest value among all the keys
        return(nearest, subdict[nearest], paths[nearest])
    else: #not found, no path from source to typeofnode
        return(None, None, None)

Test: 测试:

 find_nearest('entrance', fromnode=5)

produces: 产生:

 (7, 2.8, [5, 4, 6, 7])

Meaning: The nearest 'entrance' node from 5 is 7, the path length is 2.8 and the full path is: [5, 4, 6, 7]. 含义:距离5最近的“入口”节点为7,路径长度为2.8,完整路径为:[5、4、6、7]。 Hope this helps you move forward. 希望这可以帮助您前进。 Please ask if anything is not clear. 请询问是否不清楚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python:NetworkX查找包含给定节点列表的最短路径 - Python: NetworkX Finding shortest path which contains given list of nodes Networkx 在图中查找不同最短路径之间的公共节点 - 是否有替代解决方案? - Networkx finding common nodes between different shortest paths in a graph - Is there a alternate solution? networkx中具有“关键”节点可访问的最短路径 - Shortest Path in networkx with 'key' nodes to visit 如何使用 NetworkX 在加权图中获得最短路径? - How to get the shortest path in a weighted graph with NetworkX? 在 NetworkX 中找到加权图的最短路径长度 - Find the shortest path length of a weighted graph in NetworkX Networkx图:查找给定节点集中的任何节点与另一组节点之间是否存在路径 - Networkx graph: finding if path exists between any node in a given set of nodes and another set of nodes 是否有可能找到一个起始节点和多个目的节点之间的最短路径? 使用 Networkx 或 OSMnx - is it possible to find the shortest path between an origin node and multiple destination nodes? Using Networkx or OSMnx Networkx 忽略最短路径中具有特定属性值的节点 - Networkx ignore nodes with certain values for attributes in shortest path Networkx节点上的多个属性可用于图形上的多个标签 - Networkx multiple attributes on nodes for multiple labels on graph 我的功能有什么问题? 使用numpy和networkx查找最短路径 - What is wrong with my function? Finding the shortest path using numpy and networkx
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM