我有一个矩形网格形DAG,水平边缘总是指向右边,垂直边缘总是指向下方。边缘具有与它们相关的正成本。由于矩形格式,使用从零开始的行/列来引用节点。这是一个示例图:
现在,我想进行搜索。起始顶点始终位于左列(索引为0的列)和图的上半部分。这意味着我将选择开头为(0,0),(1,0),(2,0),(3,0)或(4,0)。目标顶点始终位于右列(索引为6的列)中,并且“对应”起始顶点:
起始顶点(0,0)对应于目标顶点(5,6)
起始顶点(1,0)对应于目标顶点(6,6)
start vertex(2,0)对应于目标顶点(7,6)
起始顶点(3,0)对应于目标顶点(8,6)
start vertex(4,0)对应于目标顶点(9,6)
我只提到这一点,以证明目标顶点始终可以访问。这对我的实际问题可能不是很重要。
我想知道的是我应该使用哪种搜索算法来查找从开始到目标的路径?我正在使用C ++并可以访问Boost Graph Library。
对于那些感兴趣的人,我正试图从他的Optimal Surface Reconstruction from Planar Contours论文中实施Fuchs的建议。
我看了A *但是说实话并不理解它,并不是启发式的工作方式,甚至我是否能想出一个!
由于矩形形状和规则的边缘方向,我认为可能有一个非常适合的算法。我考虑过Dijkstra
但我提到的论文说有更快的算法(但令我讨厌的是没有提供实现),加上那个
单一来源,我想我想要单对。
答案 0 :(得分:1)
所以,这是你的问题,
您可以使用简单的详尽搜索来定义每条可能的路线。所以你有一个O(NxN)算法。然后你会选择最短的路径。这不是一个非常聪明的解决方案,但它很有效。
但我想你想比这更聪明,让我们考虑如果可以从两个节点到达一个特定节点,你可以找到两个节点的最小权重加上到达当前节点的成本。您可以将此视为以前详尽搜索的扩展。
请记住,可以在一行中绘制DAG。对于 DAG线性化 here是一个有趣的资源。
现在你刚刚定义了一个递归算法。
MinimumPath(A,B) = MinimumPath(MinimumPath(A,C)+MinimumPath(A,D)+,MinimumPath(...)+MinimumPath(...))
当然递归的起点是
MinimumPath(Source,Source)
当然是0。 据我所知,没有开箱即用的算法来提升这样做。但实现它非常简单。
良好的实施是here。
如果由于某种原因,你没有DAG,应该使用Dijkstra或Bellman-Ford。
答案 1 :(得分:0)
如果我没有弄错的话,从解释来看,这确实是一个最佳路径问题,而不是搜索问题,因为目标是已知的。在优化中,如果您想要最佳路径而不是近似路径,我认为您不能避免进行详尽的搜索。
从纸上看,你似乎真的很多次细分空间然后运行算法。这会使你的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)
填好桌子后,从右下角开始。从您的目标开始,选择以最低成本到达该节点。向后工作选择最低值,直到到达起始节点(或者更确切地说是与起始节点对应的数组条目)。这应该非常简单地为您提供最佳路径。
动态编程通过解决较小子问题的优化来实现。在这种情况下,子问题是到前面节点的最佳路径。我认为图表的矩形特性非常适合。