Самый быстрый способ найти m x n подматрицу в матрице M X N

Я думал о быстром методе поиска подматрицы m в большей mtrix M. Мне также необходимо определить частичные совпадения.

Несколько подходов, о которых я мог подумать, следующие:

  • Оптимизируйте обычную команду bruteforce для обработки только инкрементных строк и столбцов.
  • Может быть расширен алгоритм Рабина-Карпа до 2-го, но не уверен, как обрабатывать частичные совпадения с ним.

Я считаю, что это довольно часто встречается в обработке изображений, и было бы полезно, если бы кто-то мог влить их в исходные данные или указать мне на ресурсы/документы по этой теме.

РЕДАКТИРОВАТЬ: Меньший пример:

Большая матрица:
1 2 3 4 5
4 5 6 7 8
9 7 6 5 2

Меньшая матрица:
7 8
5 2

Результат: (строка: 1 col: 3)

Пример Меньшей матрицы, которая квалифицируется как частичное совпадение в (1, 3):
7 9
5 2

Если более половины пикселей совпадают, то это делается как частичное совпадение.

Спасибо.

Ответы

Ответ 1

Я рекомендую делать интернет-поиск по "алгоритмам сопоставления двух аргументов". Вы получите много результатов. Я просто свяжу первый хит в Google, документ, который представляет собой алгоритм для вашей проблемы.

Вы также можете взглянуть на цитаты в конце статьи, чтобы получить представление о других существующих алгоритмах.

Резюме:

Представлен алгоритм поиска двухмерного шаблона m x m в двумерном n x n тексте. Он выполняет в среднем меньше сравнений, чем размер текста: n ^ 2/m, используя m ^ 2 дополнительного пространства. В основном, он использует несколько совпадений строк только для строк n/m текста. Он работает не более чем 2n ^ 2 раза и близок к оптимальному n ^ 2 времени для многих моделей. Он неуклонно распространяется на не зависящий от алфавита алгоритм с аналогичным наихудшим случаем. Экспериментальные результаты включены в практическую версию.

Ответ 2

Для этого есть очень быстрые алгоритмы, если вы хотите предварительно обработать матрицу и если у вас много запросов для одной и той же матрицы.

Взгляните на статьи по алгебраическим базам данных Исследовательской группой по мультимедийным базам данных (проф. Клаузен, Боннский университет). Посмотрите на эту статью, например: http://www-mmdb.iai.uni-bonn.de/download/publications/sigir-03.pdf

Основная идея состоит в том, чтобы обобщить перевернутый список, поэтому они используют любое алгебраическое преобразование вместо простых сдвигов в одном направлении, как с обычными перевернутыми списками.

Это означает, что этот подход работает всякий раз, когда изменения, которые вам нужно сделать для входных данных, можно моделировать алгебраически. В частности, все запросы, которые транслируются в любом количестве измерений, поворачиваются, переворачиваются и т.д., Могут быть восстановлены.

В основном это делается для музыкальных данных, так как это их основной исследовательский интерес, но вы можете найти других, которые также показывают, как адаптировать это к данным изображения (или вы можете попытаться адаптировать его самостоятельно, если вы понимаете принцип это довольно просто).

Edit

Эта идея также работает с частичными совпадениями, если вы правильно определяете их.

Ответ 3

Невозможно сделать это быстро, если вам понадобится только одна малая матрица для одной большой матрицы. Но если вам нужно сделать много маленьких матриц против больших матриц, то предварительно обработать большую матрицу.

Простой пример, точное совпадение, много матриц 3x3 против одной гигантской матрицы.

Создайте новую "матрицу соответствия", такую ​​же, как "большая матрица". Для каждого места в большой матрице вычислите хэш 3 × 3 для каждого x, y до x + 3, y + 3 в большой матрице. Теперь вы просто просматриваете матрицу соответствия для сопоставления хэшей.

Вы можете получить частичные совпадения со специализированными хеш-функциями, которые дают один и тот же хэш тем вещам, которые имеют те же свойства частичного согласования. Tricky.

Если вы хотите ускорить работу и иметь для этого память, создайте хеш-таблицу для матрицы соответствия и найдите хеши в хеш-таблице.

Решение 3x3 будет работать для любой тестовой матрицы 3x3 или более. Вам не нужно иметь идеальный хеш-метод - вам нужно просто что-то, что отклонит большинство неудачных совпадений, а затем выполнит полное совпадение для потенциальных совпадений в хеш-таблице.

Ответ 4

Я думаю, вы не можете просто догадаться, где подматрица с некоторым подходом, но вы можете оптимизировать свой поиск.

Например, учитывая матрицу 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 раз, если ваша подматрица не имеет только 1 размер.