想象一下,我正在公园里实施Dijkstra的算法。这些点之间有点和连接;这些指定用户可以走的有效路径(例如人行道)。
现在假设用户在草地上(即不在路径上)并且想要导航到另一个位置。问题不在于Dijkstra的算法(工作正常),问题在于确定在哪个顶点开始。
以下是问题的图片:(暂时忽略虚线)
黑线显示Dijkstra算法的边缘;同样,紫色圆圈显示顶点。人行道是灰色。你猜对了,草是绿色。用户位于红星,并希望转到橙色X 。
如果我天真地寻找最近的顶点并将其用作我的起点,则用户通常被引导到次优路径,这涉及在开始时离目的地更远(即红色固体路径< /强>)。
蓝色实体路径是我的算法最理想的最佳路径。
注意:
如何有效和正确地实现这一目标?
创意#1:找到封闭的多边形
如果我找到围绕起点的最小多边形,我现在可以从起点(将临时添加为新顶点)为Dijkstra算法创建新路径到构成多边形的每个顶点。在上面的示例中,多边形有6个边,因此这意味着为每个顶点创建6条新路径(即蓝色虚线)。然后我就可以运行Dijkstra的算法,它很容易确定蓝色实线是最佳路径。
此方法的问题在于确定哪些顶点包含围绕我的点的最小多边形。我不能创建图中每个顶点的新路径,否则我最终会得到红色虚线,这完全违背了使用Dijkstra算法的目的(我不应该被允许越过一条人行道)。因此,我必须注意只创建到封闭多边形顶点的路径。有算法吗?
此解决方案还有另一个复杂因素:想象用户现在从紫色闪电开始。它没有封闭的多边形,但算法仍应通过将其连接到右上角的3个点来工作。再一次,一旦它连接到那些,运行Dijkstra很容易 更新:我们想要连接到这三个点中的一个点而不是四处走动以直接到达橙色X的原因是因为我们希望最小化在未铺设的路径上完成的步行。 (注意:如果你在一个多边形之外开始,这只是一个约束。我们不关心你在草地上走多长时间,如果它在多边形内。)
如果这是正确的解决方案,请将其算法作为答案发布。
否则,请发布更好的解决方案。
答案 0 :(得分:1)
你可以从目标运行Dijkstra开始,找到它到所有顶点的距离。
现在让我们考虑一下你开始&#34;内部&#34;草地上的图。我们想要找到我们可以通过直线到达的所有顶点,而不会越过任何边缘。为此,我们可以将表示边的所有线段和将起点连接到每个顶点的线段放在一起,并使用sweep-line algorithm来查找起始顶点线是否与任何边相交。
或者,您可以对planar point location使用任何离线算法,这些算法也适用于扫描线。我相信这是在问题中提出的更抽象算法的精神,因为它报告围绕该点的多边形。
然后我们只需要找到到起点的连接线不与任何边相交的顶点,并且和d(顶点,目标)+ d(顶点,起点)最小。
当顶点在图表之外的过程有点不明确,但我想完全相同的想法是可行的。请记住,如果图表位于边框上,则可以在图表周围走动,就像在您的示例中一样。
这可能在每个查询的O((n + m)log m)中实现。如果您运行all-pairs shortest path algorithm作为预处理步骤并使用在线点位置算法,则可以以存储信息所需空间为代价获得对数查询时间,以加快最短路径查询(如果您只是存储,则为二次方)所有距离对)。
我认为简单的平面点位置就像扫描线接近一样,只有persistent个BST来存储所有扫描线状态。
答案 1 :(得分:0)
我不确定为什么你在尝试找到起始顶点时会感到困扰。您(用户)所站的位置本身就是另一个顶点。所以现在真正的问题是找到起始点到封闭多边形图形中任何其他点的距离。一旦你拥有了它,你可以简单地运行Dijkstra或其他最短路径算法方法,如A *,BFS等,以找到到达目标点的最短路径。
就此而言,我认为你最好为这个问题实施A *因为公园涉及树木,游乐场,池塘(有时候)等等。所以你需要使用最短路径算法将这些带入考虑,A *是一种使用这些因子来确定最短路径的算法。
查找从开始到图表的距离:
只需查找与起点最接近x
或y
坐标的点,即可找到从新顶点到其他顶点的距离。因此,该算法必须找到在起始点周围形成一种闭合的点,即包含该点的最小面积的多边形。正如@Niklas B所建议的那样,平面点算法(有一些修改)可能能够实现这一点。我正在研究扫描线算法,但这只适用于线段,因此不起作用(仍然值得一试,修改可能会给出正确的答案)。
你也可以决定分阶段实现这个算法,所以首先找到与当前点最接近 y
坐标的点(负y和正y,所以必须使用绝对值) ,然后在这些点中,找到与当前点具有最接近x
坐标的那些点,并且应该为您提供形成多边形的点集。然后,这些是您用来查找从开始到图表的距离的点。