2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Все вхождения одной матрицы в другую
Сообщение19.10.2009, 14:38 


19/10/09
2
Даны две бинарные (состоящие только из 0 и 1) матрицы. Какими способами (кроме банального брутфорса) можно найти все вхождения одной матрицы в другую?

 Профиль  
                  
 
 Re: Все вхождения одной матрицы в другую
Сообщение19.10.2009, 15:29 
Заслуженный участник


09/08/09
3438
С.Петербург
Если поиск однократный, то единственное, что приходит на ум - это искать брутфорсом, слегка модифицированным аналогично алгоритму Бойера — Мура поиска строки в подстроке.
Если надо искать несколько матриц $M\times N$ в матрице $P\times Q$, то можно попробовать сформировать новую матрицу $(P-M+1)\times(Q-N+1)$, поместив в ячейку $(i,j)$ хэш, рассчитанный по подматрице $[i..i+M-1, j..j+N-1]$ исходной матрицы. После этого можно сравнивать не элементы матриц, а хэши, и проверять равенство элементов только если хэши совпали.
В любом случае, целезообразность использования того или иного способа надо оценивать "по месту" :)

 Профиль  
                  
 
 Re: Все вхождения одной матрицы в другую
Сообщение19.10.2009, 15:39 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
Может иметь смысл перевод матриц в формат машинных слов, тратя по одному биту на элемент. Тогда техническую работу можно перевести на операции над 32- или 64-битными цепочками (сдвиги и сравнения), т.е. 64 элемента матрицы будут сравниваться зараз за одну машинную операцию.

 Профиль  
                  
 
 Re: Все вхождения одной матрицы в другую
Сообщение19.10.2009, 18:12 


19/10/09
2
Поиск однократный (то есть ищутся все вхождения в данную матрицу только одной данной подматрицы).

Цитата:
Если поиск однократный, то единственное, что приходит на ум - это искать брутфорсом, слегка модифицированным аналогично алгоритму Бойера — Мура поиска строки в подстроке.

Можно подробнее? Вы предлагаете представить матрицы в виде строк?

Цитата:
Может иметь смысл перевод матриц в формат машинных слов, тратя по одному биту на элемент. Тогда техническую работу можно перевести на операции над 32- или 64-битными цепочками (сдвиги и сравнения), т.е. 64 элемента матрицы будут сравниваться зараз за одну машинную операцию.

Боюсь, что это бессмысленно: в 63 случаях из 64 придётся работать с битами из двух разных цепочек. Займёт ещё больше времени.
Хотя идея интересная. При необходимости минимизировать выделяемую память имела бы смысл. Быть может, идея имеет смысл при наличии некоторых эвристик-предположений о входных данных (например, если предположить, что обе матрицы состоят в основном из огромных нулевых или единичных кусков).

Существует ещё вариант (описанный в статье "Efficient Processing for Binary Submatrix Matching" -- http://www.scipub.org/fulltext/ajas/ajas6178-88.pdf):
Например, есть матрица
Код:
0 0 0 0 1 1
1 1 1 1 1 1
1 1 0 0 1 1
0 0 1 1 0 1
0 0 0 0 1 1
1 1 1 0 0 0

Она представляется в виде
Код:
4 2
0 6
0 2 2 2
2 2 1 1
4 2
0 3 3

(то есть 4 нуля, 2 единицы, 0 нулей, 6 единиц, и так далее)

Аналогично представляется искомая подматрица. Это просто.
А далее “matrix submatching algorithm” по построенным матрицам выглядит громоздким и плохо, сумбурно описанным. Может быть, у кого-нибудь есть лучший вариант (если вдобавок реализованный на языке программирования -- ещё лучше)?

 Профиль  
                  
 
 Re: Все вхождения одной матрицы в другую
Сообщение19.10.2009, 18:34 
Заслуженный участник


09/08/09
3438
С.Петербург
tlf в сообщении #253031 писал(а):
Цитата:
Если поиск однократный, то единственное, что приходит на ум - это искать брутфорсом, слегка модифицированным аналогично алгоритму Бойера — Мура поиска строки в подстроке.

Можно подробнее? Вы предлагаете представить матрицы в виде строк?

Нет, идея состоит в том, что если очередное сравнение оказалось неудачным, то во многих случаях можно сдвигать "окно" по большей матрице не на одну, а на несколько позиций.
Например, если первая строка меньшей матрицы
Код:
0 0 0 1
а первая строка большей
Код:
0 0 1 0 . . .
то после обнаружения несовпадения в позиции 2 (считая с 0), мы можем сдвинуть "окно" не в позицию 1, а сразу в позицию 3.

-- Пн окт 19, 2009 19:40:06 --

Для этого перед началом поиска меньшую матрицу надо обсчитать аналогично тому, как это делается с образцом в алгоритме Бойера-Мура.

 Профиль  
                  
 
 Re: Все вхождения одной матрицы в другую
Сообщение20.10.2009, 11:12 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
tlf в сообщении #253031 писал(а):
Боюсь, что это бессмысленно: в 63 случаях из 64 придётся работать с битами из двух разных цепочек. Займёт ещё больше времени.


Нет, Вы ошибаетесь. Смотрите. Допустим, мы работаем с 64-битными целыми. Пусть первые 64 элемента первой строки матрицы записаны в переменной a, следующие 64 бита - в b, а первые 64 бита первой строки искомой подматрицы записаны в v.

Пусть мы хотим проверить, совпадают ли 64 бита подматрицы с битами основной матрицы начиная, скажем, с 10-й позиции. Для этого нужно сравнить v со следующим значением:
Код:
(a<<10)|(b>>54)


То есть сравнение 64 бит происходит одновременно и на него тратится всего два сдвига, один побитовый OR и одно сравнение 64-битных целых. Учтите также, что побитовые операции - самые быстрые в процессоре, быстрее арифметических. Это будет работать в десятки раз быстрее, чем сравнивать по одному биту.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group