在3D二进制矩阵中查找连续单元组

时间:2012-07-31 09:28:19

标签: algorithm 3d matrix

我想在矩阵中找到一组连续的单元格。

例如,让我们考虑下面的2D矩阵。

2d binary matrix

在给定的矩阵中,有2个连续的单元格组,其值为1

contiguous 1s in binary matrix

以下是查找这些群组的一种方法:

  1. 为值为1的第一个单元格指定一个不同的值:让我们说A。然后检查与1相邻的值为A的单元格,并将这些单元格中的值设置为A。以这种方式搜索,直到找不到更多连续的单元格。

  2. 在下一步中,将A增加到B,并从值为1的单元格开始。然后按照上面的步骤进行操作。

  3. 这是一种蛮力,它在3D中效率不高。有没有人知道我可以通过一些调整使用的任何算法?

    或者解决这个问题的任何简单方法?

3 个答案:

答案 0 :(得分:5)

您尝试做的事情往往是在connected component labelling标签下。我不会进一步详细说明,维基百科的文章比我能做的更好地解释了事情。

但我正在回答......

你和许多其他人在SO上似乎认为对数组的所有元素进行简单的迭代,你可以用贬义词蛮力来表征,这是完全可以避免的。成本。现代计算机非常非常快。按顺序访问数组中的每个元素是大多数编译器可以优化地狱的原因。

您似乎陷入了以下陷阱,即在O(n^3)中访问3D数组的每个元素都具有时间复杂性,其中n是数组中每个维度的元素数。它不是:访问数组的元素在O(n)中,其中n是数组中元素的数量。

即使访问数组中每个元素的时间复杂度都在O(n^3)许多提供更好的渐近时间复杂度的复杂算法,实际上也会证明比简单算法提供更差的性能。许多复杂的算法使编译器更难以优化代码。并且,请记住,O(n^2)是算法的等价类,其中包括具有真实时间复杂度的算法,例如O(m+k*n^2),其中mk都是常量

答案 1 :(得分:3)

这是一个简单的泛洪填充算法的伪代码:

>>> def flood(i, j, matrix):
...     if 0 <= i < len(matrix) and 0 <= j < len(matrix):
...         if matrix[i][j] == 1:
...             matrix[i][j] = 0
...             for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
...                 flood(i + dx, j + dy, matrix)

>>> count = 0
>>> while True:
...     i, j = get_one(matrix)
...     if i and j: #found a one
...         count += 1
...         flood(i, j, matrix)

答案 2 :(得分:0)

这与在图表中查找strongly connected components一样,但整个事物扩展到3维。因此,您可以将任何线性时间算法用于2D图形,并使DFS也适用于第三维。这应该是直截了当的。

由于这些算法是线性时间,因此无法在运行时复杂度方面做得更好。