在 M X N 矩阵中找到 m x n 子矩阵的最快方法

Fastest way to Find a m x n submatrix in M X N matrix

本文关键字:方法      更新时间:2023-10-16

我在想一种快速的方法,在更大的mtrix M中寻找子矩阵m。我还需要识别部分匹配。

我能想到的几种方法是:

  1. 优化普通暴力破解,仅处理增量行和列。
  2. 可以将拉宾-卡普算法扩展到 2-d,但不确定如何处理部分匹配。

我相信这是图像处理中经常遇到的问题,如果有人可以倾注他们的意见或向我指出有关此主题的资源/论文,我将不胜感激。

编辑:较小的示例:

更大的矩阵:
1 2 3 4 5
4 5 6 7 8
9 7 6 5 2

更小的矩阵:
7 8
5 2

结果:(行:1 列:3(

在 (1, 3( 处限定为部分匹配的较小矩阵的示例:
7 9
5 2

如果超过一半的像素匹配,则将其视为部分匹配。

谢谢。

我建议在互联网上搜索"2D模式匹配算法"。你会得到很多结果。我将只链接谷歌上的第一个命中,这篇论文为您的问题提供了一种算法。

您还可以查看论文末尾的引文,以了解其他现有算法。

摘要:

提出了一种在二维n x n文本中搜索二维m x m模式的算法。它执行的比较平均少于文本的大小:n^2/m使用m^2额外空间。基本上,它只在文本的 n/m 行上使用多个字符串匹配。它最多运行 2n^2 次,并且接近许多模式的最佳 n^2 时间。它稳步扩展到具有类似最坏情况的独立于字母的算法。实验结果包含在实际版本中。

如果您愿意预处理矩阵并且对同一矩阵有很多查询,则有非常快速的算法。

看看多媒体数据库研究小组(波恩大学克劳森教授(关于代数数据库的论文。例如,看看这篇论文:http://www-mmdb.iai.uni-bonn.de/download/publications/sigir-03.pdf

基本思想是推广倒排列表,因此他们使用任何类型的代数变换,而不是像普通倒排列表那样只向一个方向移动。

这意味着只要需要对输入数据进行的修改可以代数建模,这种方法就有效。特别是,可以检索以任意数量的维度,旋转,翻转等方式转换的查询。

这篇论文主要针对音乐数据展示这一点,因为这是他们的主要研究兴趣,但你也许可以找到其他人,它们展示了如何将其适应图像数据(或者你可以尝试自己改编,如果你理解原理,它很简单(。

编辑

如果您正确定义部分匹配,则此想法也适用于部分匹配。

如果您只需要将一个小矩阵与一个大矩阵匹配,则无法快速完成此操作。但是,如果您需要针对大矩阵执行许多小矩阵,则对大矩阵进行预处理。

一个简单的例子,精确匹配,许多 3x3 矩阵对一个巨大的矩阵。

创建一个新的"匹配矩阵",与"大矩阵

"大小相同,对于大矩阵中的每个位置,为大矩阵中的每个 x,y 到 x+3,y+3 计算一个 3x3 哈希。现在,您只需扫描匹配矩阵以查找匹配的哈希值。

您可以使用专用哈希函数实现部分匹配,

这些函数为具有相同部分匹配属性的事物提供相同的哈希。棘手。

如果要进一步加快速度并为其提供内存,请为匹配矩阵创建哈希表,并在哈希表中查找哈希。

3x3

解决方案适用于任何 3x3 或更大的测试矩阵。你不需要有一个完美的哈希方法 - 你只需要一些可以拒绝大多数错误匹配的方法,然后对哈希表中的潜在匹配项进行完全匹配。

我认为你不能用一些方法猜测子矩阵在哪里,但你可以优化你的搜索。

例如,给定一个矩阵 A MxN 和一个子矩阵 B mxn,您可以执行以下操作:

SearchSubMatrix (Matrix A, Matrix B)
answer = (-1, -1)
Loop1:
for i = 0 ... (M-m-1)
|
|   for j = 0 ... (N-n-1)
|   | 
|   |   bool found = true
|   |
|   |   if A[i][j] = B[0][0] then
|   |   |
|   |   |   Loop2:
|   |   |   for r = 0 ... (m-1)
|   |   |   |   for s = 0 ... (n-1)
|   |   |   |   |   if B[r][s] != A[r+i][s+j] then
|   |   |   |   |   |   found = false
|   |   |   |   |   |   break Loop2
|   |
|   |   if found then
|   |   |   answer = (i, j)
|   |   |   break Loop1
|
return answer

这样做,您将减少子矩阵大小原因的搜索。

Matrix         Submatrix         Worst Case:
1 2 3 4           2 4            [1][2][3] 4
4 3 2 1           3 2            [4][3][2] 1
1 3 2 4                          [1][3]{2  4}
4 1 3 2                           4  1 {3  2}
                                 (M-m+1)(N-n+1) = (4-2+1)(4-2+1) = 9

虽然这是O(M*N),但它永远不会看M*N次,除非你的子矩阵只有一维。