【问题标题】:Finding most efficient path between two nodes in an interval graph在区间图中找到两个节点之间的最有效路径
【发布时间】:2015-04-04 16:56:03
【问题描述】:

我有区间数据:

A = (0,50)
B = (20,500)
C = (80,420)
....

并意识到这个数据有一个关联的图表,the interval graph

我想找到从 A 到 G 的最有效路径(假设我知道所有正顶点权重,wa、wb、wc...)。我需要从 A 开始到 G,所以最小生成树必须绑定在这些点之间。我们应用程序中的一个限制条件是,必须完全覆盖从 A 开始到 G 结束的区间(没有间隙)。我在看networkX's minspanning tree method,不明白如何指定A和G必须是起点和终点。

想到的其他一些问题是:

  1. 由于这个问题是 NP 难题,如果节点数很高,我是否应该费心寻找最小生成树?多少节点会太多?

  2. 注意区间 F 有一个独特的区域。换句话说,要完全覆盖区间 A-G,必须经过 F。因此,我的最小生成树可能应该只连接 A-F,而不是 A-G。给定一个更大的图,是否有一种标准方法可以找到所有区间不包含唯一补丁的子图?换句话说,由于所有路径都必须经过 F 才能到达 G,所以 A-F 是感兴趣的最小跨度路径,而不是 A-G。如何在不手动检查的情况下以这种方式缩小图形?

  3. 因为我必须从 A-G 走,所以我永远不会倒退或走循环路径。例如,我永远不会去 A-B-A。生成树是否包含这一点?这会让我的图表有方向吗?考虑点 C:从 C 可以到 D、E 或 F,但永远不会回到 A(对于我们的用例)。这对于图形的方向性意味着什么?

对于新手 Q 很抱歉,大部分内容都是新手。

【问题讨论】:

  • 对我来说这似乎不是最小生成树问题。这似乎是一个简单的最短路径问题。此外,最小生成树不是 NP 难的。它在 P 中。根据树的定义,生成树永远不会有循环。
  • 谢谢胡安。很明显,我对此很陌生。当您说最短路径时,是否考虑了节点权重。 IE C 节点/区间覆盖的距离最远,但取决于其他约束,可能会有不好的成本,因此路径 A、D、F 实际上是首选。知道在哪里可以了解有关这部分问题的更多信息吗?
  • 是的,Dijkstra 算法(以及其他几种最短路径算法)考虑了边缘的权重。在您的情况下,权重由节点定义,但您可以通过使用边缘到达的节点的权重设置边缘的权重来轻松调整。
  • FWIW,你不应该自己实现 dijkstra 的算法。它已经在 networkx 中到位(我在回答中给出了针对您的案例的代码)。
  • 另外,您应该注意,不能保证最小生成树在两个节点之间具有最短路径。考虑这个简单的观察:如果你发现任何有循环的东西的最小生成树,那么在一些 xy 之间一定有一条边,它已被删除。那么显然最小生成树没有最短路径。

标签: algorithm graph dynamic-programming graph-theory networkx


【解决方案1】:

如果您必须以一种有效的方式从 A 转到 G,那么您并不是在寻找最小生成树算法。一个简单的最短路径算法就足够了。您只需要调整图表以将权重放在边缘而不是节点中。但这只是将节点的权重设置为传入边的问题。

此外,最短路径和最小生成树问题都不是 NP 难题。所有这些问题都有已知的多项式算法。特别是,最短路径可以通过Dijkstra's algorithm 解决(如果您的图没有负边,这似乎是真的),最小生成树可以通过Prim'sKruskal's algorithm 解决。

最后,根据定义,任何树都没有循环。

【讨论】:

  • 所以我本身没有区间图,我有一棵树?
  • 不,您确实有一个区间图,但是如果您计算它的最小生成树,则可以保证它没有环,因为根据定义,树是一个无环连通图。
  • 哦,好的,谢谢!关于“将节点的权重设置为传入边”,所以边 A-C.它会有节点 A 的权重吗?
  • 没关系,你可以选择A'或C的重量。它必须在整个图表中保持一致。
  • 值得给出实际的networkx算法(我已经添加了一个答案,但最好指出这些算法已经内置到networkx中)。在这种情况下,它是dijkstra_pathnetworkx.lanl.gov/reference/algorithms.shortest_paths.html
【解决方案2】:

正如另一个答案中提到的,Dijkstra 的算法是解决方案。没有提到的是如何在 networkx 中实现该解决方案。这里是。就这么简单:

import networkx as nx
my_graph = nx.Graph()
my_graph.add_edges_from([('A','B'),('B','C'),('A','C'),('C','D'),('A','D'),('C','E'),('D','E'),('D','F'),('F','G')]) 
#graph is now defined.

shortestpath = nx.dijkstra_path(my_graph, 'A', 'G') #optional weight argument here.
shortestpath
> ['A', 'D', 'F', 'G']

一般而言,有关如何在 networkx 中执行最短路径算法(及其许多变体)的更多文档是 here

请注意,如果您在节点上有权重并且希望最小化路径中节点的总和,您所做的就是在边上放置权重,以便 (u, v) 的权重为 @987654325 @。

然后运行 ​​nx.dijkstra_path 并使用可选参数告诉 networkx 在哪里可以找到边的权重。整个路径的权重将等于中间权重的总和,加上末端节点值的一半。然后,您可以更正结束节点的权重。

【讨论】:

  • 谢谢乔尔,感谢您的分享;这会节省我很多时间。我现在明白了最短路径和生成树之间的区别,所以感谢大家澄清这一点。
  • 有没有办法像我的数据一样从区间范围构建图表? IE,我的数据集中的重叠应该自动暗示图形构造中的连通性。
  • 会有办法的。我能想到一些,但其他人可能有更好的想法(而且它需要的空间比评论所能做的更多)。您可以提出另一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-19
  • 1970-01-01
  • 2012-03-21
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 2013-07-08
相关资源
最近更新 更多