【问题标题】:Finding the starting vertex for Dijkstra's algorithm?找到 Dijkstra 算法的起始顶点?
【发布时间】:2014-06-09 02:14:15
【问题描述】:

想象一下,我正在公园里实施 Dijkstra 算法。这些点之间存在点和连接;这些指定了用户可以行走的有效路径(例如人行道)。

现在假设用户在草地上(即不在路径上)并且想要导航到另一个位置。问题不在于 Dijkstra 的算法(工作正常),问题在于确定从哪个顶点开始。

这是问题的图片:(暂时忽略虚线)

黑线表示 Dijkstra 算法中的边缘;同样,紫色圆圈显示顶点。人行道为灰色。草是,你猜对了,绿色。用户位于红星,并希望到达橙色X

如果我天真地寻找最近的顶点并将其用作起点,则用户通常会被引导到次优路径,这涉及在开始时离目的地更远(即红色实心路径)。

蓝色实心路径是我的算法理想的最佳路径。

注意事项:

  • 假设没有路径与其他路径交叉。
  • 导航到起点时,用户不应越过路径(例如人行道)。
  • 在上图中,从星星出来的第一条线段是动态创建的,只是为了帮助用户。星不是图中的顶点(因为用户可以在草地区域内的任何地方)。只是显示了从星形到顶点的线段,以便用户知道如何到达图中的第一个有效顶点。

我怎样才能有效且正确地实现这一点?


想法 #1:找到封闭的多边形

如果我找到围绕起点的最小多边形,我现在可以为 Dijkstra 算法创建从起点(将临时添加为新顶点)到构成多边形的每个顶点的新路径。在上面的示例中,多边形有 6 条边,因此这意味着为每个顶点创建 6 条新路径(即蓝色虚线)。然后我就可以运行 Dijkstra 的算法,它很容易确定蓝色实线是最佳路径。

这种方法的问题在于确定哪些顶点构成了围绕我的点的最小多边形。我不能为图中的每个顶点创建新路径,否则我最终也会得到 红色虚线,这完全违背了使用 Dijkstra 算法的目的(我不应该被允许跨越人行道)。因此,我必须注意只创建到封闭多边形顶点的路径。有这个算法吗?

此解决方案还有另一个复杂之处:假设用户现在从紫色闪电开始。它没有封闭的多边形,但是通过将其连接到右上角的 3 个点,该算法仍然可以工作。同样,一旦连接到这些点,运行 Dijkstra 就很容易了。
更新:我们想要连接到这 3 个点之一而不是绕过所有东西直接到达橙色 X 的原因是因为我们想尽量减少在未铺砌的小路上行走。 (注意:如果您从多边形外开始,这只是一个约束。如果草地在多边形内,我们不在乎您在草地上行走多长时间。

如果这是正确的解决方案,请发布其算法作为答案。

否则,请发布更好的解决方案。

【问题讨论】:

  • 我不太明白。有效路径的限制是什么?如果你从外面开始,为什么你不能从外面走到目标?
  • 还有什么是所需的运行时间? O((n+m) * log n),像 Dijkstra?

标签: algorithm dijkstra polygons


【解决方案1】:

您可以从目标开始运行 Dijkstra 以找到它到所有顶点的距离。

现在让我们考虑从草地“内部”开始的情况。我们想找到所有可以通过直线到达而不跨越任何边的顶点。为此,我们可以将表示边的所有线段和将起点连接到每个顶点的线段放在一起,并使用sweep-line algorithm 来查找起点-顶点线是否与任何边相交。

或者,您可以对planar point location 使用任何离线算法,这些算法也适用于扫描线。我相信这符合问题中提出的更抽象算法的精神,因为它报告了围绕该点的多边形。

那么我们只需要找到与起点的连接线不与任何边相交并且d(vertex, target) + d(vertex, start)之和最小的顶点。

当顶点在图形之外时的过程有点未指定,但我想完全相同的想法会起作用。请记住,如果它在边界上,则有可能围绕图形走到目标,就像在您的示例中一样。

这可能在每个查询的 O((n+m) log m) 中实现。如果您运行all-pairs shortest path algorithm 作为预处理步骤并使用在线点定位算法,您可以获得对数查询时间,代价是存储信息所需的空间以加速最短路径查询(如果您只存储所有距离,则为二次对)。

我相信简单的平面点定位就像扫描线方法一样工作,只是使用persistent BST 来存储所有扫描线状态。

【讨论】:

  • 这里的关键是在所有顶点上最小化 d(start,vertex) + d(vertex,end)。您可能会强调这一点。
  • @bgschiller 我不会说这是关键。那是微不足道的部分。关键是找到 vertex 的有效候选者
【解决方案2】:

我不知道你为什么在你已经有了一个起始顶点的情况下还要费心去寻找一个起始顶点。您(用户)所在的点本身就是另一个顶点。所以现在真正的问题是找到从你的起点到封闭多边形graph中任何其他点的距离。一旦你有了它,你可以简单地运行 Dijkstra 或其他最短路径算法方法,如 A*、BFS 等,以找到到达目标点的最短路径。

关于这一点,我认为您最好为这个问题实施 A*,因为公园涉及树木、游乐场、池塘(有时)等。因此您需要使用最短路径算法将这些内容纳入考虑,A* 是一种使用这些因素来确定最短路径的算法。

查找从起点到图形的距离:

查找新顶点到其他顶点的距离的问题可以通过只查找与您的起点坐标最近的xy 坐标来完成。因此,该算法必须找到围绕起点形成某种闭合的点,即包含该点的最小面积多边形。因此,正如@Niklas B 所建议的那样,平面点算法(经过一些修改)可能能够实现这一点。我正在查看扫描线算法,但它只适用于线段,因此不起作用(仍然值得一试,修改后可能会给出正确答案)。

你也可以决定分阶段实现这个算法,所以首先找到与当前点坐标最近的y坐标点(负y和正y,所以必须使用绝对值),然后在这些点中,您会找到与当前点最接近的x 坐标,这应该为您提供形成多边形的点集。然后这些是您用来查找从起点到图形的距离的点。

【讨论】:

  • 但是如何确保在将起点连接到其他顶点之一时不会越过路径?或者换句话说,你隐式引入的新顶点的是什么?
  • 这就是我提到的,问题不在于找到一个顶点开始,真正的问题是如何确定从你的新顶点到所有其他点的距离。一旦你有了这个,你就可以运行你选择的最短路径算法来找到最短路径。您也不必担心路径交叉,因为一个好的最短路径算法会选择最近的点。因此,如果有 2 条路径相交,则最近路径上的点将在后者之前被选择。
  • 我不同意。看看这张图:imgur.com/P1hz6Oy 十字是起点,圆圈是目标。据我了解,使用您提出的算法,它将采用连接两者的直线,但这不是有效路径
  • @NiklasB。您显示的图表上只有一个顶点,因此实际上任何试图找到从 x 到圆的最短路径的算法都将无法找到一个顶点,或者必须穿过一条路径才能找到一个顶点。我已经进行了编辑
  • 想象所有的角都是顶点(有3个)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多