Метод четырёх русских для умножения матриц

Материал из Викиконспекты
Версия от 07:11, 13 января 2012; Gr1n (обсуждение | вклад) (Оценка сложности алгоритма и выбор k)
Перейти к: навигация, поиск

Дано две квадратных матрицы A[n×n] и B[n×n], состоящие из нулей и единиц. Нужно найти их произведение. При этом, все операции выполняются по модулю 2.

Простое решение

Если мы будем считать произведение матриц C=AB по определению(ci,j=nk=1ai,kbk,j), то сложность работы алгоритма составит O(n3) — каждый из n2 элементов результирующей матрицы C вычисляется за время, пропорциональное n.

Сейчас будет показано, как немного уменьшить это время.

Сжатие матриц

Для выполнения сжатия матриц выполним следующий предподсчёт : для всех возможных пар двоичных векторов длины k подсчитаем и запомним их скалярное произведение по модулю 2.

Возьмём первую матрицу. разделим каждую её строку на куски размера k. Для каждого куска определим номер двоичного вектора, который соответствует числам, находящимся на этом куске. Если кусок получился неравным по длине k(последний кусок строки), то будем считать, что в конце в нём идут не влияющие на умножение нули. Получим матрицу An×nk.

Аналогично поступим с матрицей B, вместо строк деля столбцы. Получим матрицу Bnk×n.

Теперь, если вместо произведения матриц A и B считать произведение новых матриц A и B, воспользовавшись посчитанными скалярными произведениями, то каждый элемент матрицы C будет получаться уже за время, пропорциональное nk вместо n, и время произведения матриц сократится с O(n3) до O(n2nk)=O(n3k).

Оценка сложности алгоритма и выбор k

ExampleNew1.jpg

Оценим асимптотику данного алгоритма.

  • Предподсчёт скалярных произведений работает за O(22kk).
  • Создание матриц A и BO(n2)
  • Перемножение полученных матриц — O(n3k)

Итого: O(22kk)+O(n3k). Выбрав k=logn, получаем требуемую асимптотику O(n2logn)+O(n3logn)=O(n3logn)

Пример работы алгоритма

Рассмотрим работу алгоритма на примере перемножения двух матриц A и B, где

A= (0111010011011001) , B= (1001001110100101)

k=log2n=log24=2, то предподсчитаем все скалярные произведения:

Для удобства каждому битовому вектору будет соответствовать двоичное число с ведущими нулями, т.е. в данном случае имеем числа 00, 01, 10, 11. Ниже приведена таблица, в которой записаны все искомые произведения:

\begin{tabular}{|c|c|c|c|c|}            \hline             &  \textbf{00} & \textbf{01} & \textbf{10} & \textbf{11} \\          \hline             \textbf{00} & 0 & 0 & 0 & 0  \\            \hline             \textbf{01} & 0 & 1 & 0 & 1 \\            \hline                 \textbf{10} & 0 & 0 & 1 & 1 \\            \hline             \textbf{11} & 0 & 1 & 1 & 0\\                             \hline          \end{tabular}

Согласно соглашению относительно битовых векторов и двоичных чисел получим новые матрицы A и B:

A= (0111010011011001) , B= (1000011110011001)

Перемножим эти матрицы по модулю два с использованием нашего предпосчета:

C=A×B= (1100001111111100)

Матрица C - искомая.

Литература

  • Gregory V. BardAccelerating Cryptanalysis with the Method of Four Russians July 22, 2006. Страница 5