Algorithm 在无向图中寻找唯一循环

Algorithm 在无向图中寻找唯一循环,algorithm,graph,Algorithm,Graph,我目前正在为Unity开发一个基于节点的房屋生成器。该系统的工作流程非常简单:用户可以创建节点,即简单的立方体,并将它们相互连接以创建墙。网格处理已经完成,并且工作良好且平滑 我现在要做的是检测创建了多少个封闭的房间,以及每个房间都包含哪些顶点。可能的输入可在以下图像中看到: 在第一幅图中,循环是 (1,5,3,4)、(1,2,6,8,7,5)、(6,9,12,11,10,8)、(8,10,14,13)和(10,11,17,16,15,14) 在第二种情况下,他们会 (1,2,5,6,8,7

我目前正在为Unity开发一个基于节点的房屋生成器。该系统的工作流程非常简单:用户可以创建节点,即简单的立方体,并将它们相互连接以创建墙。网格处理已经完成,并且工作良好且平滑

我现在要做的是检测创建了多少个封闭的房间,以及每个房间都包含哪些顶点。可能的输入可在以下图像中看到:

在第一幅图中,循环是

(1,5,3,4)、(1,2,6,8,7,5)、(6,9,12,11,10,8)、(8,10,14,13)和(10,11,17,16,15,14)

在第二种情况下,他们会

(1,2,5,6,8,7)、(2,3,4,14,13,6,5)、(6,13,12,11,10)和(8,6,10,9)

每个节点最多可以连接到四个其他节点,每侧一个,每个链路存储在两侧。我不需要节点以任何特定的顺序出现

我想我可以使用一个通用的循环检测算法,递归地搜索子循环,直到我找到的循环没有内部连接,但这将非常消耗资源。一定有一些属性可以用来检测没有内部连接的循环,而无需在图上迭代太多次,但我一直无法找到它


你有什么建议吗

要使以下算法正常工作,您需要:

  • 边的唯一方向(可能已经存在)
  • 每个边的两个标志,用于指定该边是否已在向前和向后方向上使用
  • 具有未使用边的顶点列表
接下来的想法如下。取任何具有未使用边的节点,并沿任何未使用边移动到相邻节点(记住方向)。进行此操作时,立即按照使用的方向标记边缘。在这个邻居家,你知道你来的方向。按逆时针顺序查看,直到找到第一条未使用的边(再次注意边的方向)。也可以按顺时针顺序搜索,这将定义所有输出面的顺序。例如,如果您来自左边缘,则分别检查底部、右侧和顶部边缘。穿过此边(标记为已使用)并重复,直到到达起始顶点。所有访问的顶点构成您的房间

执行此操作时,应相应地更新具有未使用边的顶点列表

最终,您还将为边界创建一个面。您可以通过计算其方向来检测:

v1 x v2 + v2 x v3 + v3 x v4 + ... + vn x v1
(x1, y1) x (x2, y2) = (x1 * y2) - (x2 * y1)
,其中
v
是顶点的位置,
x
表示叉积的z分量(表示面方向):


边界面将具有与所有其他面不同的方向符号。实际符号取决于在边缘遍历过程中使用的是逆时针顺序还是顺时针顺序。

这只是对第一个问题的回答,但可能对第二个问题有所帮助。封闭房间的数量实际上有一个封闭公式:
1-V+E
其中V是顶点数,E是边数。在第二个示例中,有14个顶点、17条边和4个房间。
数学有点复杂,但关键词是。

需要补充的是,这需要连接图形。否则,Euler特性将改变。