【问题标题】:Networkx shortest path with condition on edges - pythonNetworkx最短路径与边缘条件 - python
【发布时间】:2020-01-24 10:44:21
【问题描述】:

让我们考虑以下Graph

G = nx.Graph()
G.add_nodes_from(['A', 'B', 'C', 'D', 'E', 'F'])
G.add_edges_from([('A', 'B', {'walk': 3, 'time': 3}), ('A', 'C', {'metro': 4, 'time': 4}), ('A', 'D', {'walk': 3, 'time': 3}), 
                  ('C', 'E', {'walk': 3, 'time': 3}), ('D', 'E', {'walk': 3, 'time': 3}), ('B', 'F', {'walk': 3, 'time': 3}), 
                  ('D', 'F', {'metro': 4, 'time': 4}), ('E', 'F', {'walk': 3, 'time': 3})])
nx.draw(G, with_labels=True, font_color='white')

可以看到边缘的三个属性:

  • walk 是从一站走到另一站的时间(如果可能的话)。
  • metro 是乘坐地铁从一个站点到另一个站点的时间。
  • time 等于 walkmetro 并且是我用于 nx.shortest_path 的权重(这使我无需在地铁或步行之间进行选择即可获得所需时间更少的路径)。李>

我现在想在节点AF 之间获取nx.shortest_path(G, 'A', 'F', weight='time'),路径上有一个条件:我希望shortest_path 具有尽可能少的walk 边。

在这种情况下,唯一被认为是好的 shortest_pathA -> D -> F,因为只有 1 个 walk 边,而其他边至少有两个(即使某些边的总 time 更短) .

有没有办法做到这一点?


编辑:我尝试使用nx.all_shortest_paths() 获取多个shortest_paths,然后选择符合我要求的一个,但它不起作用。 nx.all_shortest_paths() 确实在sourcetarget 之间给了我更多可能的短路径,但是它们中的walk edges 已经太多了。 一种解决方案是获得被认​​为是shortest of shortest paths 的东西,以及更短的可能有更多选择的东西。 但是,我不知道该怎么做。

【问题讨论】:

  • 你能通过将时间乘以 10 来惩罚你的步行边缘吗?计算最短路径?
  • 我试过了,还是不行。我得到的路径仍然等同于我使用常规 walk 边缘的路径,但是从 sourcetarget 需要更长的时间,同时在其中保留大量 walk 边缘。

标签: python networkx shortest-path


【解决方案1】:

使用您的示例:

原网络少“走罚”:

G = nx.Graph()
G.add_nodes_from(['A', 'B', 'C', 'D', 'E', 'F'])
G.add_edges_from([('A', 'B', {'walk': 3, 'time': 3}), ('A', 'C', {'metro': 4, 'time': 4}), ('A', 'D', {'walk': 3, 'time': 3}), 
                  ('C', 'E', {'walk': 3, 'time': 3}), ('D', 'E', {'walk': 3, 'time': 3}), ('B', 'F', {'walk': 3, 'time': 3}), 
                  ('D', 'F', {'metro': 4, 'time': 4}), ('E', 'F', {'walk': 3, 'time': 3})])
#nx.draw(G, with_labels=True, font_color='white')
nx.shortest_path(G, 'A', 'F', weight='time')

输出:

['A', 'B', 'F']

现在,让我们通过乘以 10 倍来惩罚行走边缘时间:

G = nx.Graph()
G.add_nodes_from(['A', 'B', 'C', 'D', 'E', 'F'])
G.add_edges_from([('A', 'B', {'walk': 3, 'time': 30}), ('A', 'C', {'metro': 4, 'time': 4}), ('A', 'D', {'walk': 3, 'time': 30}), 
                  ('C', 'E', {'walk': 3, 'time': 30}), ('D', 'E', {'walk': 3, 'time': 30}), ('B', 'F', {'walk': 3, 'time': 30}), 
                  ('D', 'F', {'metro': 4, 'time': 4}), ('E', 'F', {'walk': 3, 'time': 30})])
#nx.draw(G, with_labels=True, font_color='white')
nx.shortest_path(G, 'A', 'F', weight='time')

输出:

['A', 'D', 'F']

如果你对你的“行走”边缘进行足够的惩罚,你能提供一个这样的例子吗?

【讨论】:

  • 对不起,我想让帖子保持简单,但我想现在太简单了......:/最好的解决方案是分享我正在使用的Graph,但它非常庞大。我将创建一个简化的子图,其中包含一个不起作用的具体示例,并编辑我的帖子 + 答案让您知道。
  • @I.M.您可能需要调整乘法因子以在“行走”边缘获得足够的惩罚。 10 倍可能还不够。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
相关资源
最近更新 更多