【问题标题】:Find groups of contiguous cells in a 3D binary matrix在 3D 二进制矩阵中查找连续单元组
【发布时间】:2012-07-31 09:28:19
【问题描述】:

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

例如,让我们考虑下面的二维矩阵。

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

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

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

  2. 在下一步中将A 增加到B 并从具有值1 的单元格开始。然后按照与上述相同的步骤进行操作。

这是一种蛮力,在 3D 中效率不高。有谁知道我可以稍微调整一下就可以使用的任何算法?

或者有什么简单的方法可以解决这个问题?

【问题讨论】:

    标签: algorithm 3d matrix


    【解决方案1】:

    您尝试执行的操作通常位于标签connected component labelling 下。我不会进一步详细说明,维基百科的文章比我能够或愿意更好地解释问题。

    但是在我回答的时候……

    您和 SO 上的许多其他人似乎认为对数组的所有元素进行简单迭代(您用贬义词 brute-force 来描述它)是完全应该避免的费用。现代计算机非常非常快。按顺序访问数组的每个元素是大多数编译器可以优化的东西。

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

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

    【讨论】:

    • 嗯,对于连通组件标注,具有最佳时间复杂度的复杂算法(即,使用不相交集数据结构来获得O(input_size * inverseAckermann(input_size)) 性能)可以非常快速并且是选择的实用方法。
    • 也就是说,我同意在这里抱怨需要阅读整个输入的“蛮力”是愚蠢的。如果问题只是想找到一个连接的组件,它本身就已经回答了。但是如果目标是找到所有个连接的组件,那么无论如何你都需要查看整个输入......
    • 谢谢大家。是的,你是对的,我不想在贬义上使用蛮力..只是想探索是否有其他方法。谢谢大家。
    【解决方案2】:

    下面是一些简单的洪水填充算法的伪代码:

    >>> 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)
    

    【讨论】:

    • 感谢罗伯特。最终使用了 3D 的洪水填充算法。
    • 到目前为止,我实现了 Flood Fill,它正在做我需要做的事情。所以将这个作为答案。谢谢。
    • 太棒了,你能解释一下你的算法和方法吗?我问这个是为了学习。谢谢。
    • 搜索“深度优先搜索”“广度优先搜索”“洪水填充”和“联合查找”,或者试试这个:leetcode.com/problems/number-of-islands 都应该是 O(V+E) = O(NM +4NM) = O(NM) 最好的方法是遍历矩阵的单元格,如果之前没有找到单元格,则进行 DFS。
    【解决方案3】:

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

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

    【讨论】:

    • 是的。看过强连接组件。确实帮助清除了一些东西。欣赏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多