ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-09-10 13:59:17  阅读:300  来源: 互联网

标签:python graph networkx


我有一个不同位置的图表:

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)

位置(节点)有不同的类型(厕所,建筑物入口等)我需要找到从某个给定位置到特定类型的任何位置的最短路径. (例如:从给定节点查找最近的入口.)

在没有循环的情况下,Networkx库中是否有一些方法可以解决这个问题?就像是:

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

如果两个位置属于同一类型,则结果将是first_location或second_location的最短路径.

是否有一些方法也返回路径长度?

解决方法:

我们将分三步完成.

>第1步:让我们创建一个虚拟图来说明
>步骤2:绘制图形和颜色节点以指示边长和特殊节点类型(厕所,入口等)
>步骤3:从任何给定节点(源)计算到所有可到达节点的最短路径,然后子集到感兴趣的节点类型并选择具有最小长度的路径.

下面的代码肯定可以优化,但这可能更容易理解.

第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   

第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()

enter image description here

步骤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)

测试:

 find_nearest('entrance', fromnode=5)

生产:

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

含义:距离5最近的“入口”节点为7,路径长度为2.8,完整路径为:[5,4,6,7].希望这有助于您前进.请问是否有任何不清楚的地方.

标签:python,graph,networkx
来源: https://codeday.me/bug/20190910/1799103.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有