我有一个有向图,如下所示:
我想找到从开始到结束最便宜的路径,其中橙色虚线都是路径有效所必需的。
自然最短路径为:开始 - > A - > B - >结束,结果成本= 5,但我们尚未满足所有必需的边访问。
我想找到的路径(通过一般解决方案)是开始 - > A - > B - > C - > D - > B - >结束,其中费用= 7,我们已满足所有必需的边访问。
有没有人对如何要求这样的边缘遍历有任何想法?
答案 0 :(得分:2)
让 R 成为所需边的集合, F = | R |。设 G 为输入图, t (resp。 s )请求路径的起始(resp。结束)点。
第一步是创建另一个图表。该图将具有完全 F +2顶点:
要创建此图表,您必须执行以下操作:
构建此图表的复杂性为 O((F + 2)²。(E + V).log(V))其中 E ( resp。 V )是原始图表中的边数(相应的顶点)。
从这一点来说,我们必须在新创建的图中找到最短的哈密尔顿路径。不幸的是,这项任务是一个难题。我们没有比探索每条可能的道路更好的方法。但这并不意味着我们不能巧妙地做到这一点。
我们将使用回溯执行搜索。我们可以通过维护两组来实现这一目标:
在深入研究算法定义之前,这里有一些主要的想法。除了在新图中探索可能路径的整个空间之外,我们无能为力。在每一步,我们都必须做出决定:我们接下来要采取哪些方面?这导致一系列决定,直到我们不再移动或我们到达 s 。但现在我们需要回过头来取消决定,看看我们是否可以通过改变方向做得更好。要取消决定,我们会这样做:
最终算法可以用这种方式总结:(我给出了一个迭代实现,可以找到一个更简单,更清晰的递归实现)
让K
←[]
,L[0..R+1]
←[]
和U
←V(其中V是工作图中每个顶点的集合减去开始和结束顶点 t 和 s )。最后让l
←i
←0和best_path_length
←∞和best_path
←[]
虽然(i
≥0):
U
≠[]
c
←U.popFront()
(我们采取U的头)L[i].pushBack(c)
i == R+1
AND(l
==权重(cur_path.back()
, s )+ l
)< best_path_length
:
best_path_length
←l
cur_path
K.tail()
和c
之间存在边缘e,weight(e)
+ l
< best_path_length
K
:(如果K.tail()
为空,则在前一个语句中将K.pushBack(c)
替换为 t )
i
i
←l
+ 1 weight(e)
←l
+ cur_path.pushBack(c)
L[i]
U
L[i]
[]
←i
i
←cur_path.popBack()
- 1 while (i ≥ 0)
在while循环(best_path
)结束时,{{1}}将保留最佳路径(在新图中)。从那里你只需要获得边缘的有效负载来重建原始图形中的路径。