给定源节点,dest节点和中间节点,如何检测最短的曼哈顿距离是否被阻止?

时间:2012-01-08 19:01:41

标签: algorithm graph-theory

这是我要发布的完整标题,但它确实太长了:

  

给定源节点,dest节点和中间节点,如何检测中间节点是否阻塞了最短的曼哈顿距离?

an image of the problem

我画了一张图表,以便更清楚。在左侧,“u”是源节点,“v”是目标节点。标记为1到6的节点是中间节点。曼哈顿距离最短的距离 - > v将是12,但中间节点形成阻挡它的墙。右边的图表以u'为源,v'为目的地,表明中间节点1到5不会阻止从u'到v'的最短曼哈顿距离。

我正在尝试找到一种不需要我实际进行图搜索(例如BFS)的算法,因为u和v之间的距离可能非常大。

2 个答案:

答案 0 :(得分:2)

如果您要做的就是检测是否阻止了最短路径(一个由单向移动的移动组成的路径),那么您正在尝试检查阻塞节点是否切割了角落由源节点和目标节点分为两个不相连的区域。如果没有从源到目的地的最短路径,那么每条路径都必须有一些被阻挡的点。

为简单起见,我们假设您的起点位于目标点的下方和左侧。在这种情况下,在O(n)中找到包含在包含起点和终点的边界框中的所有其他点作为障碍点。您现在想要查看是否有一些节点的子集将矩形切割成两个部分,一个包含左下角,另一个包含右上角。如果阻挡节点的路径从左侧到右侧,从左侧到底侧,从顶侧到右侧,或从顶侧到底侧,则这是可能的。因此,我们只需要检查这些是否可行。

幸运的是,这可以通过将问题建模为具有大小为O(n)的图中的图搜索来有效地完成,其中n是阻塞点的数量,并且与边界框的大小无关。也就是说,无论测试点相隔多远,搜索图形的大小仅取决于阻塞点的数量。

您要构建的图表有两个部分。首先,构建一个图形,其中每个阻塞点相互连接,围绕它的3x3方块中的阻塞点。这些边缘将可能是同一障碍的一部分的阻挡点链接在一起,因为从源到目标的任何路径都不能在由边连接的两个阻挡点之间传递。现在,添加四个代表顶壁,左墙,右墙和底壁的新节点,并将它们连接到与相应墙相邻的每个节点。这样,例如,从左墙节点到右墙节点的路径将代表一系列阻塞节点,使得无法从左下方节点到达右上方节点。

此图的大小为O(n),其中n是阻塞节点的数量,因为有O(n)个节点,每个节点最多可以有12个边 - 一个用于8个邻居中的每一个,可能还有一个用于四面墙中的每一面。您可以通过扫描每个节点在最差的二次时间内构建它,并且对于每个其他节点,查看它们是否相邻。可能有更好的方法来做到这一点,但目前没有任何事情发生在我身上。

现在您已经拥有了图表,对于每对墙,如果已连接,将断开图形,在此图中在这两个墙节点之间运行图搜索。如果存在路径,则报告最短路径被阻止。如果没有,请报告某些最短路径未被阻止。这些搜索可以使用简单的DFS完成,或者因为您正在运行多个搜索,并且只想知道它们是否已连接,使用强连接组件算法一次并检查是否有任何一对重要节点位于同一SCC中。两种方法都需要时间O(n)。

因此解决这个问题的时间最多为O(n 2 ),瓶颈是构建图形所需的时间。

希望这有帮助!

答案 1 :(得分:0)

这是我的想法:

我将描述目的地从源的上方和右方的情况,对于其他情况,旋转。 (对于节点具有相同x / y坐标的简单情况,只需检查它们之间是否存在阻塞节点)

在角落中获取包含源和目标的矩阵。现在,一次一列,从左到右,在列内,自下而上,标记已阻止节点。如果以下任何一种情况属实,则节点 B 阻止

  • B 是一个中间节点
  • 留给 B 的节点和 B 的底部都被阻止(两者都已根据处理顺序进行了检查)或在矩阵的界限

最后,如果目的地被阻止,则没有免费的最短路径。

所需时间为O(m * n),其中m,n是矩阵边长。因此,当您只有几个中间节点时,templatetypedef的解决方案可能更合适。

编辑:以前有点不对,现在我希望我没有错过任何东西