<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=83.239.81.22&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=83.239.81.22&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/83.239.81.22"/>
		<updated>2026-05-20T09:07:26Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%87%D0%B5%D1%82%D1%8B%D1%80%D1%91%D1%85_%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D1%85_%D0%B4%D0%BB%D1%8F_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=71846</id>
		<title>Метод четырёх русских для умножения матриц</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%87%D0%B5%D1%82%D1%8B%D1%80%D1%91%D1%85_%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D1%85_%D0%B4%D0%BB%D1%8F_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=71846"/>
				<updated>2019-10-08T15:07:53Z</updated>
		
		<summary type="html">&lt;p&gt;83.239.81.22: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = Дано две квадратных матрицы &amp;lt;tex&amp;gt;A_{[n \times n]}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B_{[n \times n]}&amp;lt;/tex&amp;gt;, &lt;br /&gt;
состоящие из нулей и единиц. Нужно найти их произведение. При этом, все операции выполняются по модулю &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{#if: {{{neat|}}}|&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #fcfcfc; float:left;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: #ddd;&amp;quot;&amp;gt;'''Задача:'''&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px dashed #2f6fab; padding: 8px; font-style: italic;&amp;quot;&amp;gt;{{{definition}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;|&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;background-color: #ddd&amp;quot;&amp;gt;'''Задача:'''&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td style=&amp;quot;border:1px dashed #2f6fab; padding: 8px; background-color: #fcfcfc; font-style: italic;&amp;quot;&amp;gt;{{{definition}}}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;}}&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
== Простое решение ==&lt;br /&gt;
&lt;br /&gt;
Если мы будем считать произведение матриц &amp;lt;tex&amp;gt;C = A \cdot B&amp;lt;/tex&amp;gt; по определению &amp;lt;tex dpi=130&amp;gt;\left(c_{i, j} = \sum\limits_{k = 1}^n a_{i,k}b_{k,j}\right)&amp;lt;/tex&amp;gt;, то сложность работы алгоритма составит &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt; {{---}} каждый из &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; элементов результирующей матрицы &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; вычисляется за время, пропорциональное &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сейчас будет показано, как немного уменьшить это время.&lt;br /&gt;
&lt;br /&gt;
== Сжатие матриц == &lt;br /&gt;
&lt;br /&gt;
Для выполнения сжатия матриц выполним следующий предподсчёт : для всех возможных пар двоичных векторов длины &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; подсчитаем и запомним их скалярное произведение по модулю &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Возьмём первую матрицу. разделим каждую её строку на куски размера &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. Для каждого куска определим номер двоичного вектора, который соответствует числам, находящимся на этом куске. Если кусок получился неравным по длине &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;(последний кусок строки), то будем считать, что в конце в нём идут не влияющие на умножение нули. Получим матрицу &amp;lt;tex dpi=140&amp;gt;A'_{n \times \lceil\frac{n}{k} \rceil}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Аналогично поступим с матрицей &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;, вместо строк деля столбцы. Получим матрицу &amp;lt;tex dpi=140&amp;gt;B'_{\lceil\frac nk\rceil\times n}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь, если вместо произведения матриц &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; считать произведение новых матриц &amp;lt;tex&amp;gt;A'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt;, воспользовавшись посчитанными скалярными произведениями, то каждый элемент матрицы &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; будет получаться уже за время, пропорциональное &amp;lt;tex&amp;gt;\lceil \dfrac{n}{k} \rceil&amp;lt;/tex&amp;gt; вместо &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, и время произведения матриц сократится с &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;O(n^2 \cdot\dfrac nk) = O(\dfrac{n^3}{k}) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Оценка сложности алгоритма и выбор k ==&lt;br /&gt;
[[Файл:exampleFourRussiansAlgoFinalPicture.png|500px|right]]&lt;br /&gt;
&lt;br /&gt;
Оценим асимптотику данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
* Предподсчёт скалярных произведений работает за &amp;lt;tex&amp;gt;O(2^{2k}k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Создание матриц &amp;lt;tex&amp;gt;A'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Перемножение полученных матриц {{---}} &amp;lt;tex&amp;gt;O(\dfrac{n^3}{k})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итого: &amp;lt;tex&amp;gt;O(2^{2k}k) + O(\dfrac{n^3}{k})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Выбрав  &amp;lt;tex&amp;gt;k = \log n &amp;lt;/tex&amp;gt;, получаем требуемую асимптотику &amp;lt;tex&amp;gt;O(n^2 \log n) + O(\dfrac{n^3}{\log n}) = O(\dfrac{n^3}{\log n})&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим работу алгоритма на примере перемножения двух матриц &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt;, где &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\left(\begin{array}{cccc}  &lt;br /&gt;
           0 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1 \\  &lt;br /&gt;
           0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\  &lt;br /&gt;
           1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 1 \\  &lt;br /&gt;
           1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 &lt;br /&gt;
        \end{array}\right)&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
, &amp;lt;tex&amp;gt; B = &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\left(\begin{array}{cccc}  &lt;br /&gt;
           1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\  &lt;br /&gt;
           0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 \\  &lt;br /&gt;
           1 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 \\  &lt;br /&gt;
           0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 1 &lt;br /&gt;
        \end{array}\right)&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; k = \log_2 n = \log_2 4 = 2&amp;lt;/tex&amp;gt;, то предподсчитаем все скалярные произведения:&lt;br /&gt;
&lt;br /&gt;
Для удобства каждому битовому вектору будет соответствовать двоичное число с ведущими нулями, т.е. в данном случае имеем числа &amp;lt;tex&amp;gt; 00 &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; 01 &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; 10 &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; 11 &amp;lt;/tex&amp;gt;. Ниже приведена таблица, в которой записаны все искомые произведения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{|c|c|c|c|c|}  &lt;br /&gt;
         \hline  &lt;br /&gt;
          &amp;amp;  \textbf{00} &amp;amp; \textbf{01} &amp;amp; \textbf{10} &amp;amp; \textbf{11} \\&lt;br /&gt;
         \hline  &lt;br /&gt;
          \textbf{00} &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0  \\  &lt;br /&gt;
         \hline  &lt;br /&gt;
          \textbf{01} &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 1 \\  &lt;br /&gt;
         \hline      &lt;br /&gt;
          \textbf{10} &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 \\  &lt;br /&gt;
         \hline  &lt;br /&gt;
          \textbf{11} &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 &amp;amp; 0\\                   &lt;br /&gt;
         \hline  &lt;br /&gt;
       \end{array} &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Согласно соглашению относительно битовых векторов и двоичных чисел получим новые матрицы &amp;lt;tex&amp;gt; A' &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; B' &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A' = &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\left(\begin{array}{cccc}   &lt;br /&gt;
           01 &amp;amp; 11 \\  &lt;br /&gt;
           01 &amp;amp; 00 \\  &lt;br /&gt;
           11 &amp;amp; 01 \\  &lt;br /&gt;
           10 &amp;amp; 01 &lt;br /&gt;
        \end{array}\right)&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
,&lt;br /&gt;
&amp;lt;tex&amp;gt; B' = &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\left(\begin{array}{cccc}  &lt;br /&gt;
           10 &amp;amp; 00 &amp;amp; 01 &amp;amp; 11 \\    &lt;br /&gt;
           10 &amp;amp; 01 &amp;amp; 10 &amp;amp; 01 &lt;br /&gt;
        \end{array}\right)&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Перемножим эти матрицы по модулю два с использованием нашего предпосчета:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = A'  \times B' = &amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\left(\begin{array}{cccc}  &lt;br /&gt;
           1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\  &lt;br /&gt;
           0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 \\  &lt;br /&gt;
           1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1 \\  &lt;br /&gt;
           1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 &lt;br /&gt;
        \end{array}\right)&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;tex&amp;gt; C &amp;lt;/tex&amp;gt; {{---}} искомая.&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* ''Gregory V. Bard'' — ''Accelerating Cryptanalysis with the Method of Four Russians''. July 22, 2006. Страница 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Динамическое программирование]]&lt;br /&gt;
[[Категория: Способы оптимизации методов динамического программирования]]&lt;/div&gt;</summary>
		<author><name>83.239.81.22</name></author>	</entry>

	</feed>