在无向图中查找多边形

Posted

技术标签:

【中文标题】在无向图中查找多边形【英文标题】:Finding polygons within an undirected Graph 【发布时间】:2012-04-05 22:37:36 【问题描述】:

请看图片:http://i.stack.imgur.com/NPUmR.jpg

我有一个包含一个或多个连接子图的无向图。该图由一组有序的连接顶点对定义。最多可以有 300 个顶点。该图是平面的。

我需要识别如图所示的多边形。单独多边形中的每个彩色区域。粗略的启发式可能是多边形是图中闭合边缘循环(循环)之间的“封闭区域”。在类似的帖子中建议可以使用深度优先遍历和标记访问的顶点来识别循环。

但是,我不确定在此之后如何进行以获得所需的输出,如图所示。

要求:

i) 多边形不得重叠或相交。即: Cycle ABFHDCA 不是有效的多边形,因为它会与 Polygon FHGE 重叠。循环 ABFEGHDCA 是一个有效的多边形。

ii) 多边形可能有 3 条或更多条边,并且多边形必须以图的边为界。 XYZ 是一个有效的多边形,尽管它与 Graph 的其余顶点断开了连接。

iii) 像 K 和 L(即叶子)这样的顶点不构成多边形的一部分。我们不关心边缘 JK。

更新: iv) 在图中,边不相互交叉。两条边唯一可以相遇的地方是一个顶点。前面的阶段/算法保证是这种情况。

问题:

    我是否在正确的轨道上使用 DF 遍历查找循环方法? DF 遍历是否会给我在这种情况下需要考虑的所有(简单)循环,尤其是 XYZ 与图表的其余部分断开连接?

    是否有解决此问题的现有替代算法?

补充说明:

a) 我在用更具体的计算几何术语定义这个问题时遇到了麻烦,所以我坚持在无向图中寻找多边形。我必须承认,我学习图论已经有好几年了。我现在正在刷它。

b)对此的解决方案似乎不像凹/凸壳算法。我们谈论的是一组连接的边 - 真正的多边形,而不仅仅是需要包含的点云。

c) 上面的例子是我可以在短时间内想出的。我认为它涵盖了大多数“边缘”案例(双关语):)

类似的解决方案

    我发现了一个类似的帖子,但the accepted solution 似乎没有为此示例生成正确的循环。

提前致谢!

【问题讨论】:

我认为 DFS 是找到图中所有循环的好方法。然后你想从长度为 3 的循环开始并将它们定义为多边形。接下来,您需要查看下一个循环大小,并检查是否没有一组顶点已经构成了整个定义的多边形 - 如果没有,那么这个循环是一个新的多边形。继续,直到你的周期用完。 感谢您的回答海伦。这可能会给我们一些结果。但是这里有一些失败的案例。考虑移动多边形 XYZ 使其完全包含在 EFGH 中。您的策略将首先产生 XYZ,然后产生 EFGH 作为可接受的多边形,而忽略明显的重叠。我想我们可以通过测试每个多边形的每个顶点来解决这个问题,这样它就不会包含在另一个多边形中。也就是说,除了 Edge chechs 之外,我们还在执行区域检查。但这不是很优雅,而且可能很昂贵。想法? 昨晚我在考虑这个问题,但我认为这个问题定义得不够明确,无法解决。由于示例图可以通过多种方式绘制为平面图,我认为您不能只输入一组顶点和边并获得解决方案输出。如果 I,J 在 A,B,C,D 矩形内,而 E,G 在外面呢?为了检查多边形是否重叠,您需要知道它们是如何相互绘制的。您真的可以使用坐标集而不是顶点集。 嗨,Helen,对于我的问题集,我可以保证边缘永远不会相交。如果边确实相遇,它们将始终在顶点处相遇。因此,多边形要么 a) 完全被包围,要么 b) 共享一组共同的边,或者 c) 与给定的多边形完全分离。这是通过管道中的先前完整性阶段来确保的。我会更新问题以反映这一点。 好的,在这种情况下使用 DFS 查找所有循环。然后遍历所有循环以找到其中没有其他循环的循环。将它们定义为多边形。再次遍历循环以找到仅具有已定义多边形且其中没有其他循环的循环,并将这些新循环(减去其中的现有多边形)定义为多边形。重复,直到你的周期用完。 【参考方案1】:

提取平面图区域的最优算法:http://www.sciencedirect.com/science/article/pii/016786559390104L

您要做的是从嵌入式平面图中提取多边形/区域。该算法在上面的论文中给出。时间复杂度为 \Omega (m \logm),空间复杂度为 \Omega (m),其中 m 是图中的边数。

【讨论】:

欢迎来到 SO。我很欣赏您链接到的论文是付费论文,但在这里发布仅链接答案通常不受欢迎,因为链接腐烂使答案毫无意义。【参考方案2】:

首先,让我们摆脱退化的边(在您的示例中为JKJL):找到具有单边的顶点并将它们从图中删除。请注意,此删除还可能会创建另一个退化边,因此每次删除顶点A 和边AB 时,再查看顶点B,看看它现在是否也退化了。

现在请注意,虽然每个顶点都可以包含在任意数量的多边形中,但每条边恰好包含两个。因此,我建议我们可以通过越过边缘而不是顶点来让自己的生活变得更简单。

    将两个布尔字段与每条边相关联,以记录是否找到了leftright 多边形。这些字段最初应该都是false。 选择任意一条边,我们称之为AB
      如果AB.rightfalse
        创建一个空列表L 用于存储多边形边 将AB.right 设置为true 并将AB 添加到L 迭代顶点B 的边以找到多边形的下一条边。想象一下,您正在从A 开车到B,下一个边缘是迫使您在B 做出最急右转弯的边缘。我确信边缘向量的点积将使这个搜索变得微不足道,但我回忆起细节已经太久了。 为下一条边递归执行步骤 2 和 3(将 right 变量设置为 true 并将边添加到 L),直到遇到 right 已经是 true 的边。这将是您开始的边缘 - 您已经找到了一个完整的多边形,并且您已经从搜索空间中消除了一堆边缘!
      如果AB.leftfalse,则执行与上述相同的过程,只是这次您是在相反的方向行驶(从BA)并且您正在设置left 字段随你去true。请注意,您仍在尝试在每个顶点处进行尽可能锐利的右转。这将生成另一个多边形并从您的搜索中消除另一束边。
    重复直到每条边的leftright 字段为true

我们将生成一个多边形列表,但此列表将包含一些我们不想要的多边形 - 包含您飞机外部空间的多边形(在您的示例图像中,这些将是 XZYACDHJIB)。这些可以通过检查the winding order of the vertices 来检测。我们在每个顶点都向右转,所以我们想要的多边形将显示顺时针缠绕顺序。

【讨论】:

以上是关于在无向图中查找多边形的主要内容,如果未能解决你的问题,请参考以下文章

从坐标图中绘制多边形画布

在多边形 PHP 中查找点

在地图上查找城市或区域的多边形

查找其中点的多边形

在给定多边形坐标的情况下查找点属于哪个多边形的算法

如何在 Elasticsearch 中查找包含给定点的多边形