繁体   English   中英

将布尔矩阵转换为图结构的有效方法?

[英]Efficient way to turn a boolean matrix into a graph structure?

我正在研究一个迷宫问题,其中迷宫以二维数组表示,因此,如果元素为false,则正方形将无法遍历,反之亦然。 我实现了一种求解方法,该方法以深度优先的方式递归尝试遍历起点的所有相邻正方形,该方法应能正常工作。

但是,我想击败DFS算法,并且我想到了将迷宫简化为图形的想法(也许尝试为边缘分配权重),并在图形上执行DFS,而不是在图中的每个正方形迷宫。 我遇到的问题是,我将迷宫变成抓斗的方式似乎效率很低。 这是将布尔矩阵变成图形的方法的概述:

我从第0行开始,遍历从索引0、0到索引n,0的每一行,然后从0,1 .. n,1直到n,n。 编辑:澄清一下:我先让迷宫的x值增加。 然后,在下一段中垂直链接节点。

我将矩阵中的真值称为空心正方形。 *如果板的边缘上有一个白色正方形,我将在Node类中创建一个新的子类Opening。 我将保留对该节点的引用。 继续向右,如果我遇到一个十字路口,或者如果下一个正方形是黑色的,我将在两者之间建立一个节点和一个端点。 如果我从一个黑色的正方形过渡到一个白色的正方形,并且如果右边的下一个正方形不是黑色,则创建一个节点,并在该节点和该行的下一个节点之间建立一条边。

将所有节点添加到节点列表中。 然后,我遍历(0,0),(0,1),...,(0,n),(1,0),(1,1)..(1,n)的所有列。并在所有未用黑色正方形分隔的节点之间制作边线。

感觉这是处理事情的非常昂贵的方法。 我很想听听有关如何正确完成此操作的任何建议。

F F F F F F F F F F F F F
T T F T T T T T T T T T F
F T F F F F F F F T F F F
F T T T F T T T F T F T F
F F F T F T F T F F F T F
F T F T F T F T T T T T F
F T F T F T F F F F F F F
F T T T F T T T T T T T F
F T F F F F F F F F F T F
F T F T T T T T T T T T F
F T F T F F F F F F F T F
F T T T F T T T T T T T T
F F F F F F F F F F F F F

将使这些节点:

. . . . . . . . . . . . .
O O . O . . . . . O . O .
. . . . . . . . . . . . .
. O . O . O . O . . . . .
. . . . . . . . . . . . .
. . . . . . . O . . . O .
. . . . . . . . . . . . .
. O . O . O . . . . . O .
. . . . . . . . . . . . .
. . . O . . . . . . . O .
. . . . . . . . . . . . .
. O . O . O . . . . . O O
. . . . . . . . . . . . .

这没有显示边缘,但是也许您知道了。

我有两个解决方案,其中一个已经实施。 在我开始解释第一种算法之前,这里需要假设一些算法:

假设条件

  1. 就以下方面而言,迷宫是最小的:迷宫的边界砖包含可行走的砖T或整个迷宫仅由不可行走的砖F构成。
  2. 迷宫定义了一个矩形或换句话说:迷宫的每一行都有相同数量的列。

算法

我将通过使用一个更简单的示例来解释该算法,仍然涉及许多重要情况。 考虑以下由5行3列组成的迷宫:

在此处输入图片说明

步行砖T为绿色,而墙砖F为蓝色。

该算法的第一阶段从(x,y)=(0,0)开始,通过访问顺时针移动的边界砖来寻找可步行的边界砖 它更喜欢步行边缘少于或多于2个的可行走瓷砖。 开放边缘是我们知道一个节点但不知道另一个伙伴节点的边缘。

它从图块(x,y)=(0,0)开始,并找到具有2个开放边可行走节点(用白色箭头表示)。 它存储候选节点(由橙色圆圈表示)并继续,以期找到如上所述的首选节点。

在步骤5,找到具有3个开放边缘的由图块(2、2)表示的优选节点。 它将节点标记为unprocessed (表示为带有白色或灰色背景的圆圈),并终止第一阶段。

第二阶段将选择任意unprocessed节点并通过确定开放边缘伙伴节点对其进行unprocessed ,直到不再存在unprocessed节点为止。 之后,它将标记该节点为已processed 确定伙伴节点可能导致将其他节点标记为unprocessed

在此处输入图片说明

唯一可以选择的unprocessed节点是第一阶段中位于(2,2)的边界节点 算法选择它(由背景为灰色的圆圈表示)。 任意选择的开放边缘表示为灰色箭头(在我们的示例中为南方)。

现在,该算法通过沿walkable图块移动直到找到一个节点(一个具有少于或多于2个边缘的图块,或者是该算法开始的图块)来搜索伙伴节点

在我们的案例中,算法在步骤6中找到了由可步行图块(0,2)表示的伙伴节点 由于此节点既未标记为已processedunprocessed标记为unprocessed因此将其标记为unprocessed (用白色背景的圆圈表示)。 现在, 打开的边 linked到其伙伴节点 (用黑色箭头表示),反之亦然。

在此处输入图片说明

该算法继续选择选定节点的开放边缘 ,直到所有开放边缘都链接到其伙伴节点 在我们的示例中,下一个任意拾取的开放边指向西。

该算法沿着可行走的切片移动,并找到由切片(0,2)表示的伙伴节点 ,该节点之前已找到该节点 ,并已将其标记为unprocessed 因此,它链接了两个节点的开放边缘 ,并继续指向北的最后一个开放边缘

它找到与以前相同的节点,并链接最后一个开放边 现在,在(2,2)处的选定节点不再具有开放的边缘 ,因此该算法将其标记为已processed (由具有绿色背景的圆圈表示)。

该算法继续选择任意一个unprocessed节点,在(0,2)处找到由图块表示的唯一一个可用节点。 但是由于此节点没有任何开放边缘 ,因此会立即将其标记为已processed并继续。

没有更多unprocessed节点可用,因此算法终止。

适用于OP示例

如果应用于您提供的示例,则结果图将更小,而不会丢失有关导航迷宫的任何信息。 让我们看一下您的图形(由于缺少一些节点,我必须完成它):

在此处输入图片说明

左图显示的是您的示例和建议的算法得出的图形。 右图显示了我所描述的算法找不到的节点,因为可以在不丢失任何导航信息的情况下对其进行优化。 它们要么被边缘取代,要么被完全消除。 结果如下所示:

在此处输入图片说明

左图显示了替换项,而右图只是其压缩版本。 该图从25个节点减少到8个节点,从23个边缘减少到7个边缘。 总体上减少了2/3个节点和边缘。

有趣的角落案例

在实施算法时,我发现了一些有趣的特例,我想与您分享。 我将匆忙完成算法以保持图像较小。 我希望您已经了解了该算法的工作原理。

  1. 单个可行走瓷砖,因此完全没有边缘:

在此处输入图片说明

  1. 仅寄宿生砖是可步行的

在此处输入图片说明

  1. 所有瓷砖都可步行

在此处输入图片说明

  1. 较好的边界砖具有单边:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM