Matlab中查找满足特定条件的子矩阵的最优方法
二进制子矩阵查找问题解决方案
问题概述
咱们先把需求和背景理清楚:给定下面这个仅含0和1的矩阵:
0 1 1 1 0 0 0 1 1 1 1 0 1 1 0 0 1 0 0 1 0 0 1 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1
我们需要找出所有满足以下两个条件的子矩阵(只需要记录子矩阵四个角的行、列索引即可):
- 条件1:子矩阵中至少包含L个1,同时至少包含L个0;
- 条件2:子矩阵的总元素数量不能超过H。
举个实际例子:当L=1、H=5时,行索引1-2、列索引1-4的子矩阵内容为:
0 1 1 1 1 1 1 1
它满足条件1(有1个0、7个1,均≥1),但总元素数为8,超过了H=5,因此不符合要求。
可行求解思路
基础遍历法(适合小规模矩阵)
- 枚举所有可能的子矩阵边界:遍历所有左上角坐标
(r1, c1)和右下角坐标(r2, c2),需保证r2 ≥ r1、c2 ≥ c1; - 先做快速筛选:计算子矩阵总元素数
(r2 - r1 + 1) * (c2 - c1 + 1),如果该数值大于H,直接跳过这个子矩阵,无需后续统计; - 统计元素计数:遍历子矩阵内的每个元素,统计1的数量,0的数量可通过总元素数减去1的数量得到,再检查两者是否都≥L;
- 记录有效结果:若两个条件都满足,就把
(r1, c1, r2, c2)记录为符合要求的子矩阵边界。
优化方案(适合较大规模矩阵)
如果矩阵规模不小,基础遍历的效率会偏低,咱们可以用前缀和矩阵来优化统计速度:
- 构建前缀和矩阵:预处理一个
prefix矩阵,其中prefix[i][j]代表从矩阵左上角(0,0)到(i-1, j-1)的子矩阵中1的总数; - 快速计算子矩阵的1的数量:对于任意子矩阵
(r1,c1)到(r2,c2),1的数量可以通过公式直接计算:count_1 = prefix[r2+1][c2+1] - prefix[r1][c2+1] - prefix[r2+1][c1] + prefix[r1][c1] - 推导0的数量:
count_0 = 子矩阵总元素数 - count_1,无需遍历子矩阵就能得到两个计数,大幅提升效率。
通过以上方法,就能高效找出所有符合要求的子矩阵啦。
内容的提问来源于stack exchange,提问作者sound wave
相关产品推荐
相关产品推荐

