最短路径图算法帮助Boost
Posted
技术标签:
【中文标题】最短路径图算法帮助Boost【英文标题】:Shortest path graph algorithm help Boost 【发布时间】:2014-01-15 17:21:50 【问题描述】:我有一个矩形网格形状的 DAG,其中水平边缘始终指向右侧,垂直边缘始终指向下方。边缘具有与之相关的正成本。由于矩形格式,使用从零开始的行/列来引用节点。这是一个示例图:
现在,我要执行搜索。起始顶点将始终位于左列(索引为 0 的列)和图形的上半部分。这意味着我将选择起点为 (0,0)、(1,0)、(2,0)、(3,0) 或 (4,0)。目标顶点始终位于右列(索引为 6 的列)并且“对应”于起始顶点:
起始顶点(0,0)对应目标顶点(5,6)
起始顶点(1,0)对应目标顶点(6,6)
起始顶点(2,0)对应目标顶点(7,6)
起始顶点(3,0)对应目标顶点(8,6)
起始顶点(4,0)对应目标顶点(9,6)
我提到这个只是为了证明目标顶点总是可以到达的。这对我的实际问题可能不是很重要。
我想知道我应该使用什么搜索算法来找到从起点到终点的路径?我正在使用 C++ 并且可以访问 Boost Graph Library。
对于那些感兴趣的人,我正在尝试实施 Fuchs 在他的 Optimal Surface Reconstruction from Planar Contours 论文中提出的建议。
我查看了 A*,但说实话并没有理解它,也不是启发式的工作原理,甚至我是否能想出一个!
由于矩形形状和规则的边缘方向,我认为可能有一个非常适合的算法。我考虑过 Dijkstra
但我提到的论文说有更快的算法(但对我来说很烦人并没有提供实现),而且那是
单源,我想我想要单对。
【问题讨论】:
【参考方案1】:所以,这是你的问题,
-
DAG 没有循环
权重 > 0
左重
您可以使用简单的详尽搜索来定义每条可能的路线。所以你有一个 O(NxN) 算法。然后你会选择最短的路径。这不是一个非常聪明的解决方案,但它是有效的。
但我想你想比这更聪明,让我们考虑一下,如果可以从两个节点到达特定节点,你可以找到两个节点上的最小权重加上到达当前节点的成本。您可以将其视为先前详尽搜索的扩展。
请记住,DAG 可以绘制成一条直线。对于DAG 线性化,here 是一个有趣的资源。
现在您已经定义了一个递归算法。
MinimumPath(A,B) = MinimumPath(MinimumPath(A,C)+MinimumPath(A,D)+,MinimumPath(...)+MinimumPath(...))
当然递归的起点是
MinimumPath(Source,Source)
当然是 0。 据我所知,boost 没有开箱即用的算法来做到这一点。但这很容易实现。
一个好的实现是here。
如果由于某种原因您没有 DAG,则应使用 Dijkstra 或 Bellman-Ford。
【讨论】:
感谢您的回复。鉴于我不熟悉树/图遍历,我需要做一些调查来理解/实现你的答案。这是一个附带项目,因此可能需要一些时间。同时,如果其他人知道现有的 BGL 算法是否能很好地做到这一点,请告诉我。 我认为您可以使用答案中发布的代码轻松完成此操作。我提到实现的地方。【参考方案2】:如果我没记错的话,从解释来看,这实际上是一个最佳路径问题,而不是搜索问题,因为目标是已知的。在优化中,如果您想要最佳路径而不是近似路径,我认为您无法避免进行详尽的搜索。
从论文看来,您实际上是在多次细分空间然后运行算法。这会使你的 N 在整个表面的情况下更接近一个常数,使 O(N^2) 不那么糟糕。
话虽如此,动态规划可能是一个很好的策略,其中 N 将受到起始节点和目标节点之间的差异的限制。这是基因组比对的示例。只是一个插图,让您了解它的工作原理。
构造一个 N × N 成本值数组,全部设置为 0 或某个默认值。
#
For i in size N:
For j in size N:
#cost of getting here from i-1 or j-1
cost[i,j] = min(cost[i-1,j] + i edge cost , cost[i,j-1] + j edge cost)
填好表格后,从右下角开始。从你的目标出发,选择到达成本最低的节点。向后选择最小值,直到到达起始节点(或者更确切地说是与起始节点对应的数组条目)。这应该非常简单地为您提供最佳路径。
动态编程通过解决较小子问题的优化来工作。在这种情况下,子问题是到前面节点的最佳路径。我认为您的图表的矩形性质使其非常适合。
【讨论】:
以上是关于最短路径图算法帮助Boost的主要内容,如果未能解决你的问题,请参考以下文章