简体   繁体   English

如何使用NetworkX获得一组路由中两个节点之间的最短路径?

[英]How to get the shortest path between two nodes in a set of routes using NetworkX?

I am using NetworkX graphs to represent a set of routes, as seen in the image below. 我正在使用NetworkX图形表示一组路由,如下图所示。

路线集

I know that NetworkX provides shortest_path() to find the shortest path between two nodes in a graph, but I want to find the shortest path considering the set of routes I have available. 我知道NetworkX提供shortest_path()来找到图中两个节点之间的最短路径,但是我想考虑我现有的一组路由来找到最短路径。 There's also weight associated with changing from one route to another. 从一条路线更改为另一条路线也会带来重担。

Right now I'm using different graphs to represent each route, but I'm not sure that's the best approach. 现在,我正在使用不同的图来表示每条路线,但是我不确定这是最好的方法。

For example: the shortest path between nodes 3 and 2 could be using only one route [3, 5, 2] or using two routes [3, 1] and [1, 2] with a cost between them. 例如:节点3和2之间的最短路径可能仅使用一条路由[3, 5, 2]或使用两条路由[3, 1][1, 2] ,并且它们之间的开销很大。

Is it possible to achieve this using NetworkX shortest_path ? 是否有可能实现这一目标使用NetworkX shortest_path

Following your idea of having multiple graphs, I'm going to create a large graph consisting of copies of each of the graphs, but also including edges between the corresponding nodes of the graphs you have. 按照您拥有多个图的想法,我将创建一个大型图,该图不仅包含每个图的副本,而且还包含您具有的图的相应节点之间的边。 So for each edge color, there is a graph with all of those edges, and for each node in the original graph there are edges between all of its copies, with some cost associated. 因此,对于每种边缘颜色,都有一个包含所有这些边缘的图形,并且对于原始图形中的每个节点,其所有副本之间都存在边缘,并附带了一些成本。 Now we'll look for paths through this bigger network. 现在,我们将寻找通过这个更大网络的路径。 It's not perfect in the sense that the code is a bit unclean, but it'll work. 从代码有点不干净的意义上来说,这并不是完美的,但是它会起作用。

import networkx as nx

nodes = [0,1,2,3,4, 5, 10, 11]
rednodes = ['r{}'.format(node) for node in nodes]   #['r0', 'r1', ...]
rededges = [('r0', 'r1'), ('r1', 'r4'), ('r4', 'r3'), ('r3', 'r5'), ('r5', 'r2')]
bluenodes = ['b{}'.format(node) for node in nodes]  
blueedges = [('b1', 'b2')]
orangenodes = ['o{}'.format(node) for node in nodes]
orangeedges = [('o1', 'o3'), ('o3', 'o11'), ('o11', 'o10')]

G = nx.Graph()
G.add_nodes_from(rednodes+bluenodes+orangenodes)

G.add_edges_from(rededges + blueedges + orangeedges, weight = 1)

#here we add edges between the copies of each node
rb_edges = [('r{}'.format(node), 'b{}'.format(node)) for node in nodes] 
ro_edges = [('r{}'.format(node), 'o{}'.format(node)) for node in nodes]
bo_edges = [('b{}'.format(node), 'o{}'.format(node)) for node in nodes]

G.add_edges_from(rb_edges+ro_edges+bo_edges, weight = 0.2)

#This next step is a bit of a hack.
#we want a short path from 0 to 11, but I can't be sure which of the colors I should 
#start in.  So I create a new 0 and 11 node, which connect to its copies with 0 cost.

temporary_edges = [(0, '{}0'.format(c)) for c in ['r', 'b', 'o']] + [(11, '{}11'.format(c)) for c in ['r', 'b', 'o']]
G.add_edges_from(temporary_edges, weight = 0)
best_option = nx.shortest_path(G, 0, 11, weight = 'weight')
G.remove_edges_from(temporary_edges)      #get rid of those edges
G.remove_nodes_from([0, 11])


print(best_option)
> [0, 'r0', 'r1', 'o1', 'o3', 'o11', 11]

That helped. 有帮助。 =) I actually created a generic function to create an extended graph, as the number of routes and the routes itself can be different. =)我实际上创建了一个通用函数来创建扩展图,因为路由数量和路由本身可以不同。 Not sure if it's written in the best way but maybe it can help anyone: 不知道它是否以最佳方式编写,但也许可以帮助任何人:

def create_extended_graph(graph, route_set, transfer_weight):

    extended_graph = nx.Graph()
    indexes = dict([(node, 0) for node in graph.nodes()])

    for route in route_set:
        for node in route:
            current_node = str(node) + '-' + str(indexes[node])
            current_node_index = node
            extended_graph.add_node(current_node, original_node=node, index=indexes[node], pos=graph.nodes()[node]['pos'])
            if route.index(node) > 0:
                tup = tuple(sorted((previous_node_index, current_node_index)))
                extended_graph.add_edge(current_node, previous_node, weight=nx.get_edge_attributes(graph, 'weight')[tup])
            indexes[node] += 1
            previous_node = current_node
            previous_node_index = current_node_index

    for node in graph.nodes():
        extended_nodes = get_list_nodes_from_att(extended_graph, 'original_node', node)

        list_combinations = combinations(extended_nodes, 2)
        for comb in list_combinations:
            extended_graph.add_edge(comb[0], comb[1], weight=transfer_weight)

    return extended_graph

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

相关问题 Python:Networkx获取具有节点和边的给定两个节点之间的路径 - Python: Networkx get path between given two nodes with nodes and edges 是否有可能找到一个起始节点和多个目的节点之间的最短路径? 使用 Networkx 或 OSMnx - is it possible to find the shortest path between an origin node and multiple destination nodes? Using Networkx or OSMnx 使用Dijkstra算法得到两个节点之间的最短路径 3d model - Using Dijkstra Algorithm to get shortest path between two nodes in 3d model 如何仅使用 networkx (shortest_path) 获取最短路径 - How to only get the shortest path with networkx (shortest_path) 如何使用 NetworkX 在加权图中获得最短路径? - How to get the shortest path in a weighted graph with NetworkX? 计算两个节点 NetworkX 之间的最长路径 - Calculate the longest path between two nodes NetworkX 是否有一个函数可以找到两个节点之间的最短路径? - Is there a function that finds the shortest path between two nodes? 两个Trie节点之间的最短路径 - Shortest Path between two Trie Nodes GraphViz,找到两个节点之间的最短路径 - GraphViz, find the shortest path between two nodes 路径中具有固定节点数的两个节点之间的最短路径 - Shortest path between two nodes with fixed number of nodes in path
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM