遍历所需边缘列表的最短路径

时间:2015-01-24 20:54:02

标签: algorithm graph shortest-path

我有一个有向图,如下所示:

Graph

我想找到从开始到结束最便宜的路径,其中橙色虚线都是路径有效所必需的。

自然最短路径为:开始 - > A - > B - >结束,结果成本= 5,但我们尚未满足所有必需的边访问。

我想找到的路径(通过一般解决方案)是开始 - > A - > B - > C - > D - > B - >结束,其中费用= 7,我们已满足所有必需的边访问。

有没有人对如何要求这样的边缘遍历有任何想法?

1 个答案:

答案 0 :(得分:2)

R 成为所需边的集合, F = | R |。设 G 为输入图, t (resp。 s )请求路径的起始(resp。结束)点。


预处理:一堆Dijkstra算法运行......

第一步是创建另一个图表。该图将具有完全 F +2顶点:

  • R
  • 中每个边缘一个
  • 一个用于您要计算的路径的起点 t
  • 一个用于您要计算的路径的 s 的结束点

要创建此图表,您必须执行以下操作:

  1. G 中删除 R 中的每个边缘。
  2. 对于 R 中的每个边 E =( b,e ):
    1. 计算从 t b 的最短路径以及从 e s 的最短路径。如果存在,请在“新图表”中添加将 s 链接到 E 的边缘,称量相关最短路径的长度。
    2. 对于 R \ { E }中的每个边 E' =( b',e') :
      1. 计算从 e b'的最短路径。如果存在,请在新图表中将 E 的边添加到 E',然后称量该最短路径的长度。将计算出的路径作为有效负载附加到相关边缘。
      2. 将计算出的路径作为有效负载附加到该边缘
  3. 构建此图表的复杂性为 O((F + 2)²。(E + V).log(V))其中 E ( resp。 V )是原始图表中的边数(相应的顶点)。


    彻底搜索最佳路径

    从这一点来说,我们必须在新创建的图中找到最短的哈密尔顿路径。不幸的是,这项任务是一个难题。我们没有比探索每条可能的道路更好的方法。但这并不意味着我们不能巧妙地做到这一点。

    我们将使用回溯执行搜索。我们可以通过维护两组来实现这一目标:

    • 当前探索的顶点列表: K K 已知
    • 当前未知顶点的列表: U U U

    在深入研究算法定义之前,这里有一些主要的想法。除了在新图中探索可能路径的整个空间之外,我们无能为力。在每一步,我们都必须做出决定:我们接下来要采取哪些方面?这导致一系列决定,直到我们不再移动或我们到达 s 。但现在我们需要回过头来取消决定,看看我们是否可以通过改变方向做得更好。要取消决定,我们会这样做:

    • 每当我们被困(或找到路径)时,我们取消我们做出的最后决定
    • 每次我们在某个时候做出决定时,我们会记录哪个决定,所以当我们回到这一点时,我们知道不会采取同样的决定并探索其他可用的决定。
    • 我们可能因为:
      • 我们找到了一条路。
      • 我们无法进一步移动(没有我们可以探索的边缘,或者我们唯一可以采取的边缘会增加当前的部分路径 - 它的长度会高于当前最佳路径的长度)。

    最终算法可以用这种方式总结:(我给出了一个迭代实现,可以找到一个更简单,更清晰的递归实现)

    K[]L[0..R+1][]U←V(其中V是工作图中每个顶点的集合减去开始和结束顶点 t s )。最后让li←0和best_path_length←∞和best_path[]

    虽然(i≥0):

    1. U[]
      1. cU.popFront()(我们采取U的头)
      2. L[i].pushBack(c)
      3. 如果i == R+1 AND(l ==权重(cur_path.back() s )+ l)< best_path_length
        1. best_path_lengthl
        2. best_path←cur_path
      4. 如果K.tail()c之间存在边缘e,weight(e) + l< best_path_length K :(如果K.tail()为空,则在前一个语句中将K.pushBack(c)替换为 t
        1. i
        2. il + 1
        3. weight(e)l + cur_path.pushBack(c)
        4. L[i]
    2. U
    3. 末尾连接L[i]
    4. []i
    5. icur_path.popBack() - 1
    6. while (i ≥ 0)
    7. 在while循环(best_path)结束时,{{1}}将保留最佳路径(在新图中)。从那里你只需要获得边缘的有效负载来重建原始图形中的路径。