Algorithm 二维网格连通性的迭代测试算法

Algorithm 二维网格连通性的迭代测试算法,algorithm,language-agnostic,flood-fill,Algorithm,Language Agnostic,Flood Fill,假设我有一个2D网格大小,可以在每个索引处容纳0或1。网格开始时充满了0,然后逐步添加1。在每一步中,我想验证添加下一个不会阻止零形成一个连接的组件(使用一个具有北、东、南和西邻居的4连接网格) 什么是迭代测试2D网格连通性的快速算法 目前,我在每次迭代中都使用泛洪填充,但我觉得应该有一个更快的算法,使用以前迭代中的信息 此外,放置迷宫的方法有时会取消放置迷宫,即使它们没有断开网格,因此我正在寻找的算法需要能够处理这一点。这是受到Kruskal迷宫生成算法的启发 我将一个正方形的邻域定义为它的8

假设我有一个2D网格大小,可以在每个索引处容纳0或1。网格开始时充满了0,然后逐步添加1。在每一步中,我想验证添加下一个不会阻止零形成一个连接的组件(使用一个具有北、东、南和西邻居的4连接网格)

什么是迭代测试2D网格连通性的快速算法

目前,我在每次迭代中都使用泛洪填充,但我觉得应该有一个更快的算法,使用以前迭代中的信息


此外,放置迷宫的方法有时会取消放置迷宫,即使它们没有断开网格,因此我正在寻找的算法需要能够处理这一点。

这是受到Kruskal迷宫生成算法的启发

我将一个正方形的邻域定义为它的8个周围正方形,包括网格的外部(一个角正方形的邻域是它的3个周围正方形加上外部,总共4个“正方形”)

将1放在一组中,使相邻的任意两个1属于同一组。将网格外部视为一个大1(这意味着第一个集合包含它)。添加1时,只需检查其邻居

下面是所有可能的情况。为了便于可视化,我将从1开始对集合编号,并在包含1的每个正方形中使用集合编号而不是1。外部属于编号为1的集合。您还可以使用它来简化实现。括号表示新放置的1

如果新1没有相邻的1,则它属于一个新集合

 0 0 0 0 0
 0 2 0 0 0
 0 0 0[3]0
 0 0 0 0 0
 0 0 1 0 0
如果它有一个相邻的1,则它属于同一集合

 0 0 0 0 0
 0 2 0 0 0
 0 0[2]0 0
 0 0 0 0 0
 0 0 1 0 0
如果它有多个相邻的1,并且属于同一集合的所有邻居都是直接邻居,则可以合并这些集合,并且新的1属于结果集合。您不需要检查是否存在断开连接

 0 0 0 0 0                0 0 0 0 0
 0 2 0 0 0                0 1 0 0 0
 0 0[3]1 0       ->       0 0[1]1 0
 0 0 1 1 0                0 0 1 1 0
 0 0 1 0 0                0 0 1 0 0

 0 0 0 0 0                0 0 0 0 0
 0 2 0 0 0                0 1 0 0 0
 0 2 0 1 0       ->       0 1 0 1 0
[3]0 0 1 0               [1]0 0 1 0
 1 1 1 0 0                1 1 1 0 0
 0 0 0 0 0                0 0 0 0 0 <- first group of 0s
 0 2 0 0 0                0 1 0 0 0
 0 0[3]1 0       ->       0 0[1]1 0
 0 1 0 1 1                0 1 0 1 1
 1 0 0 0 0                1 0 0 0 0 <- second group of 0s

 0 0 0 0 0 <- first group of 0s
 0 0 1 0 0
 0 1 0 1 1 
[1]1 0 0 0
 0 0 0 0 0 <- second group of 0s

 0 0 0 0 0                0 0 0 0 0
 0 2 0 0 0                0 1 0 0 0
 0 2 0 1 0       ->       0 1 0 1 0
[3]0 0 1 0               [1]0 0 1 0
 0{1}1 0 0      lone 0 -> 0{1}1 0 0
如果同一集合中有多个相邻的1,但它们并非都是直接相邻的,则您有一个断开连接

 0 0 0 0 0                0 0 0 0 0
 0 2 0 0 0                0 1 0 0 0
 0 0[3]1 0       ->       0 0[1]1 0
 0 0 1 1 0                0 0 1 1 0
 0 0 1 0 0                0 0 1 0 0

 0 0 0 0 0                0 0 0 0 0
 0 2 0 0 0                0 1 0 0 0
 0 2 0 1 0       ->       0 1 0 1 0
[3]0 0 1 0               [1]0 0 1 0
 1 1 1 0 0                1 1 1 0 0
 0 0 0 0 0                0 0 0 0 0 <- first group of 0s
 0 2 0 0 0                0 1 0 0 0
 0 0[3]1 0       ->       0 0[1]1 0
 0 1 0 1 1                0 1 0 1 1
 1 0 0 0 0                1 0 0 0 0 <- second group of 0s

 0 0 0 0 0 <- first group of 0s
 0 0 1 0 0
 0 1 0 1 1 
[1]1 0 0 0
 0 0 0 0 0 <- second group of 0s

 0 0 0 0 0                0 0 0 0 0
 0 2 0 0 0                0 1 0 0 0
 0 2 0 1 0       ->       0 1 0 1 0
[3]0 0 1 0               [1]0 0 1 0
 0{1}1 0 0      lone 0 -> 0{1}1 0 0
0 0 0 0 0 0 0[1]1 0
0 1 0 1 1                0 1 0 1 1

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0。例如,在第二个到最后一个案例中间加1是很好的。我不明白你的意思。当你在至少两个属于同一组(包括外部)的其他1的邻居(周围的8个正方形)中放置1时,需要进行彻底的检查。我编辑了我的答案以澄清可能的情况。实际上,在任何地方都不需要洪水填充。我所说的优化与您在编辑中添加的内容相同。虽然我没有意识到它不需要彻底检查。删除1时,您可以在本地确定删除它是否会创建一个或多个新的不相交集。如果它这样做了,它的邻国将出现差距。在这种情况下,您可以在每个相邻区域上使用BFS来确定每个相邻集合的范围,并重新分配除最大集合以外的所有集合。我发现这一点的正确名称是动态连接性。本文给出了几种通用图的算法,但下面的答案更适合我的网格情况。