我正在实施一种算法来查找一组房间中的最小跨越走廊。目前我已经算出了算法,我只是想实现它。其中一部分涉及寻找给定房间的所谓“特殊点”。矩形的“特殊点”是距离另一个矩形的最远点的最小距离的点。例如:
房间R1的特殊点是v6或v7,因为两者与R1以外的矩形中的最远点具有相同的最小距离。同样,矩形R8的特殊点是v13或v14,因为它们与R8以外的矩形中的最远点具有相同的最小距离。目前,我有邻接列表中表示的点,列表中的每个相邻点。此外,我的每个房间都在邻接列表中,每个边界点都是值。我也对它所属的每个房间都有所了解。
目前我正在通过查看该点周围每个矩形中距离最远点的距离来计算特殊点。虽然这很快,但在以下示例中明显失败:
由于我目前的实施将识别V1和V2作为R9特殊点的平局,当明确V2是特殊点时(因为从V2到R3的最远点的距离明显小于从V1到V1的距离) R2中的最远点)。我可以通过计算图中所有矩形的最远点的距离并选择最小值来实现它,但我觉得有一种更有效的方法。我的想法是围绕某种方式排序房间,只检查一些房间,但我仍然没有完整的算法。有什么想法吗?
提前致谢。
答案 0 :(得分:2)
总之,我建议同时使用源矩形上的所有点运行Dijkstra算法,并修改停止条件。该算法跟踪到目前为止在搜索期间找到的当前最低特殊距离,并且不再搜索已经远远超过当前最低特殊距离的点。下面的一些伪代码,它使用字典来存储目标点=> (最佳距离,源点)映射。
enqueue all points on source rectangle
special distance = infinity
while (queue not empty) {
point = dequeue
if (distance to point < best distance found to point AND
distance to point < special distance) {
best distance found to point = distance to point
rect = rectangle of point
if (all points found in rect) {
special distance to this rect = max(distances found to this rect)
if (special distance to this rect < special distance) {
special distance = special distance to this rect
}
}
}
}
激励下面的详细信息:
你可以运行Dijkstra's algorithm以查找源矩形上每个源点的所有点到一组目标点。基本上Dijkstra的算法是广度优先搜索,如果它满足从源点找到该点的最短路径的条件,则只能从队列头部的点进一步搜索。
如果您使用此条件,您将找到所有点的最短路径。然后,您可以计算每个目标矩形的最长距离,并取最小值 - 该源点的“特殊距离”(然后重新运行源矩形上的每个点并找到最低的特殊距离)。然而,这是太多的工作,因为您将在搜索中包含很多积分,这些积分远离您的源点并且您不需要考虑。
你可以做的是保持当前在算法运行期间找到的最低特殊距离,通过找到你找到矩形的所有点并相应地更新当前最低特殊距离(它从一些高数字开始,如C中的INT_MAX
。然后你通过说它们距离源点的距离也必须小于当前最低特殊距离来增加前进点的条件(显然,如果当前点比当前最低特殊距离更远,那么你就不能做任何通过考虑从中引出的路径,可以做得更好。)
如果您要为每个矩形找到特殊点,您可能需要考虑运行Floyd–Warshall algorithm,它将计算每对点之间的最短距离。
答案 1 :(得分:1)
这不是一个完整的答案。这是为了确认/制定“特殊要点”的定义。
引用OP:
矩形的“特殊点”是具有最小值的点 到另一个矩形的最远点的距离。
这是我的理解。
房间v*
的特殊点r
由:
其中
V_r
是房间r
R
是所有房间的集合D(v,v')
是两个给定顶点之间的距离所以,人们可以看到:
v'
选择尽可能远离v
v'
必须位于目标会议室r'
内,选择该会议室以最小化距离如果我对这个定义不太远,
那么你应该只用3个嵌套循环来强制搜索v*(r)
。
当然,您对更有效的方法感兴趣。但是,我们首先要确保正确理解“特殊要点”。