Все о геологии :: на главную страницу! Геовикипедия 
wiki.web.ru 
Поиск  
  Rambler's Top100 Service
 Главная страница  Конференции: Календарь / Материалы  Каталог ссылок    Словарь       Форумы        В помощь студенту     Последние поступления
   Геология | Книги
 Обсудить в форуме  Добавить новое сообщение
Next: 4.4. Как отличить составное Up: 4. Алгоритмические проблемы теории Previous: 4.2. Система шифрования RSA Contents: Содержание

4.3. Сложность теоретико-числовых алгоритмов

Сложность алгоритмов теории чисел обычно принято измерять количеством арифметических операций (сложений, вычитаний, умножений и делений с остатком), необходимых для выполнения всех действий, предписанных алгоритмом. Впрочем, это определение не учитывает величины чисел, участвующих в вычислениях. Ясно, что перемножить два стозначных числа значительно сложнее, чем два однозначных, хотя при этом и в том, и в другом случае выполняется лишь одна арифметическая операция. Поэтому иногда учитывают еще и величину чисел, сводя дело к так называемым битовым операциям, т.е. оценивая количество необходимых операций с цифрами 0 и 1, в двоичной записи чисел. Это зависит от рассматриваемой задачи, от целей автора и т.д.

На первый взгляд странным также кажется, что операции умножения и деления приравниваются по сложности к операциям сложения и вычитания. Житейский опыт подсказывает, что умножать числа значительно сложнее, чем складывать их. В действительности же, вычисления можно организовать так, что на умножение или деление больших чисел понадобится не намного больше битовых операций, чем на сложение. В книге [7] описывается алгоритм Шенхаге - Штрассена, основанный на так называемом быстром преобразовании Фурье, и требующий $ O(n \ln n \ln\!\ln n)$ битовых операций для умножения двух $ n$-разрядных двоичных чисел. Таким же количеством битовых операций можно обойтись при выполнении деления с остатком двух двоичных чисел, записываемых не более, чем $ n$ цифрами. Для сравнения отметим, что сложение $ n$-разрядных двоичных чисел требует $ O(n)$ битовых операций.

Говоря в этой главе о сложности алгоритмов, мы будем иметь в виду количество арифметических операций. При построении эффективных алгоритмов и обсуждении верхних оценок сложности обычно хватает интуитивных понятий той области математики, которой принадлежит алгоритм. Формализация же этих понятий требуется лишь тогда, когда речь идет об отсутствии алгоритма или доказательстве нижних оценок сложности. Более детальное и формальное обсуждение этих вопросов см. в главе 2.

Приведем теперь примеры достаточно быстрых алгоритмов с оценками их сложности. Здесь и в дальнейшем мы не будем придерживаться формального описания алгоритмов, стараясь в первую очередь объяснить смысл выполняемых действий.

Следующий алгоритм вычисляет $ a^d \mod{m}$ за $ O(\ln m)$ арифметических операций. При этом, конечно, предполагается, что натуральные числа $ a$ и $ d$ не превосходят по величине $ m$.



1. Алгоритм вычисления $ a^d \mod{m}$

  • Представим $ d$ в двоичной системе счисления $ d=d_02^r+\cdots+d_{r-1}2+d_r$, где $ d_i$, цифры в двоичном представлении, равны 0 или 1, $ d_0=1$.
  • Положим $ a_0=a$ и затем для $ i=1,\dots ,r$ вычислим

    \begin{displaymath}
a_i\equiv a_{i-1}^2\cdot a^{d_i}\pmod m.
\end{displaymath}

  • $ a_r$ есть искомый вычет $ a^d \mod{m}$.


  • Справедливость этого алгоритма вытекает из сравнения

    \begin{displaymath}
a_i\equiv a^{d_02^i+\dots+d_i}\pmod m,
\end{displaymath}

    легко доказываемого индукцией по $ i$.

    Так как каждое вычисление на шаге 2 требует не более трех умножений по модулю $ m$ и этот шаг выполняется $ r\leq \log_2 m$ раз, то сложность алгоритма может быть оценена величиной $ O(\ln m)$.

    Второй алгоритм - это классический алгоритм Евклида вычисления наибольшего общего делителя целых чисел. Мы предполагаем заданными два натуральных числа $ a$ и $ b$ и вычисляем их наибольший общий делитель $ (a,b)$.



    2. Алгоритм Евклида

  • Вычислим $ r$ - остаток от деления числа $ a$ на $ b$, $ a=bq+r, 0\leq r<b$.
  • Если $ r=0$, то $ b$ есть искомое число.
  • Если $ r\ne0$, то заменим пару чисел $ \< a,b\> $ парой $ \< b,r\> $ и перейдем к шагу 1.


  • Не останавливаясь на объяснении, почему алгоритм действительно находит $ (a,b)$, докажем некоторую оценку его сложности.

    Теорема 3.   При вычислении наибольшего общего делителя $ (a,b)$ с помощью алгоритма Евклида будет выполнено не более $ 5p$ операций деления с остатком, где $ p$ есть количество цифр в десятичной записи меньшего из чисел $ a$ и $ b$.

    Доказательство. Положим $ r_0=a>b$ и определим $ r_1, r_2, \dots, r_n$ - последовательность делителей, появляющихся в процессе выполнения шага 1 алгоритма Евклида. Тогда

    \begin{displaymath}r_1=b, \dots, \quad 0\leq r_{i+1} < r_i, \quad i=0,1,\dots n-1.\end{displaymath}

    Пусть также $ u_0=1, u_1=1, u_{k+1}=u_k+u_{k-1},  k\geq1$, - последовательность Фибоначчи. Индукцией по $ i$ от $ i=n-1$ до $ i=0$ легко доказывается неравенство $ r_{i+1}\geq u_{n-i}$. А так как $ u_n\geq10^{(n-1)/5}$, то имеем неравенства $ 10^p>b=r_1\geq u_n\geq 10^{(n-1)/5}$ и $ n<5p+1$. $ \qedsymbol$

    Немного подправив алгоритм Евклида, можно достаточно быстро решать сравнения $ ax\equiv1\pmod b$ при условии, что $ (a,b)=1$. Эта задача равносильна поиску целых решений уравнения $ ax+by=1$.



    3. Алгоритм решения уравнения $ ax+by=1$

  • Определим матрицу $ E=\begin{pmatrix}1&0\ 0&1\end{pmatrix}$.
  • Вычислим $ r$ - остаток от деления числа $ a$ на $ b$, $ a=bq+r, 0\leq r<b$.
  • Если $ r=0$, то второй столбец матрицы $ E$ дает вектор $ \begin{pmatrix}
x\ y
\end{pmatrix}$ решений уравнения.
  • Если $ r\ne0$, то заменим матрицу $ E$ матрицей $ E\cdot\begin{pmatrix}
0&1\ 1& -q
\end{pmatrix}$.
  • Заменим пару чисел $ \< a,b\> $ парой $ \< b,r\> $ и перейдем к шагу 1.


  • Если обозначить через $ E_k$ матрицу $ E$, возникающую в процессе работы алгоритма перед шагом 2 после $ k$ делений с остатком (шаг 1), то в обозначениях из доказательства теоремы 1 в этот момент выполняется векторное равенство $ \< a,b\> \cdot E_k=\< r_{k-1},r_k\> $. Его легко доказать индукцией по $ k$. Поскольку числа $ a$ и $ b$ взаимно просты, имеем $ r_n=1$, и это доказывает, что алгоритм действительно дает решение уравнения $ ax+by=1$. Буквой $ n$ мы обозначили количество делений с остатком, которое в точности такое же, как и в алгоритме Евклида.

    Три приведенных выше алгоритма относятся к разряду так называемых полиномиальных алгоритмов. Это название носят алгоритмы, сложность которых оценивается сверху степенным образом в зависимости от длины записи входящих чисел (см. подробности в главе 2). Если наибольшее из чисел, подаваемых на вход алгоритма, не превосходит $ m$, то сложность алгоритмов этого типа оценивается величиной $ O(\ln^c m)$, где $ c$ - некоторая абсолютная постоянная. Во всех приведенных выше примерах $ c=1$.

    Полиномиальные алгоритмы в теории чисел - большая редкость. Да и оценки сложности алгоритмов чаще всего опираются на какие-либо не доказанные, но правдоподобные гипотезы, обычно относящиеся к аналитической теории чисел.

    Для некоторых задач эффективные алгоритмы вообще не известны. Иногда в таких случаях все же можно предложить последовательность действий, которая, ``если повезет'', быстро приводит к требуемому результату. Существует класс так называемых вероятностных алгоритмов, которые дают правильный результат, но имеют вероятностную оценку времени работы. Обычно работа этих алгоритмов зависит от одного или нескольких параметров. В худшем случае они работают достаточно долго. Но удачный выбор параметра определяет быстрое завершение работы. Такие алгоритмы, если множество ``хороших'' значений параметров велико, на практике работают достаточно эффективно, хотя и не имеют хороших оценок сложности.

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

    Как пример, рассмотрим вероятностный алгоритм, позволяющий эффективно находить решения полиномиальных сравнений по простому модулю. Пусть $ p$ - простое число, которое предполагается большим, и $ f(x)\in \ZZ[x]$ - многочлен, степень которого предполагается ограниченной. Задача состоит в отыскании решений сравнения
    \begin{displaymath}
f(x)\equiv0\pmod p.
\end{displaymath} (8)

    Например, речь может идти о решении квадратичных сравнений, если степень многочлена $ f(x)$ равна $ 2$. Другими словами, мы должны отыскать в поле $ \FF_p=\ZZ/p\ZZ$ все элементы, удовлетворяющие уравнению $ f(x)=0$.

    Согласно малой теореме Ферма, все элементы поля $ \FF_p$ являются однократными корнями многочлена $ x^p-x$. Поэтому, вычислив наибольший общий делитель $ d(x)=(x^p-x,f(x))$, мы найдем многочлен $ d(x)$, множество корней которого в поле $ \FF_p$ совпадает с множеством корней многочлена $ f(x)$, причем все эти корни однократны. Если окажется, что многочлен $ d(x)$ имеет нулевую степень, т.е. лежит в поле $ \FF_p$, это будет означать, что сравнение (8) не имеет решений.

    Для вычисления многочлена $ d(x)$ удобно сначала вычислить многочлен $ c(x)\equiv x^p\pmod{f(x)}$, пользуясь алгоритмом, подобным описанному выше алгоритму возведения в степень (напомним, что число $ p$ предполагается большим). А затем с помощью аналога алгоритма Евклида вычислить $ d(x)=(c(x)-x,f(x))$. Все это выполняется за полиномиальное количество арифметических операций.

    Таким образом, обсуждая далее задачу нахождения решений сравнения (8), мы можем предполагать, что в кольце многочленов $ \FF_p[x]$ справедливо равенство

    \begin{displaymath}
f(x)=(x-a_1)\cdot\ldots\cdot(x-a_n),\quad a_i\in \FF_p, a_i\ne a_j.
\end{displaymath}



    4. Алгоритм нахождения делителей многочлена $ f(x)$
    в кольце $ \FF_p[x]$

  • Выберем каким-либо способом элемент $ \delta\in\FF_p$.
  • Вычислим наибольший общий делитель
    $ g(x)=(f(x),(x+\delta)^{\frac{p-1}{2}}-1) $.
  • Если многочлен $ g(x) $ окажется собственным делителем $ f(x)$, то многочлен $ f(x)$ распадется на два множителя и с каждым из них независимо нужно будет проделать все операции, предписываемые настоящим алгоритмом для многочлена $ f(x)$.
  • Если окажется, что $ g(x)=1 $ или $ g(x)=f(x) $, следует перейти к шагу 1 и, выбрав новое значение $ \delta$, продолжить выполнение алгоритма.


  • Количество операций на шаге 2 оценивается величиной $ O(\ln p) $, если вычисления проводить так, как это указывалось выше при нахождении $ d(x)$. Выясним теперь, сколь долго придется выбирать числа $ \delta$, пока на шаге 2 не будет найден собственный делитель $ f(x)$.

    Количество решений уравнения $ (t+a_1)^{\frac{p-1}{2}}=
(t+a_2)^{\frac{p-1}{2}} $ в поле $ \FF_p$ не превосходит $ \frac{p-3}{2} $. Это означает, что подмножество $ D\subset \FF_p $, состоящее из элементов $ \delta$, удовлетворяющих условиям

    \begin{displaymath}
(\delta+a_1)^{\frac{p-1}{2}}\ne(\delta+a_2)^{\frac{p-1}{2}},
\quad
\delta\ne -a_1, \delta\ne-a_2,
\end{displaymath}

    состоит не менее, чем из $ \frac{p-1}{2} $ элементов. Учитывая теперь, что каждый ненулевой элемент $ b\in\FF_p $ удовлетворяет одному из равенств $ b^{\frac{p-1}{2}}=1 $, либо $ b^{\frac{p-1}{2}}=-1 $, заключаем, что для $ \delta\in D $ одно из чисел $ a_1, a_2 $ будет корнем многочлена $ (x+\delta)^{\frac{p-1}{2}}-1$, а другое - нет. Для таких элементов $ \delta$ многочлен $ g(x) $, определенный на шаге 2 алгоритма, будет собственным делителем многочлена $ f(x)$.

    Итак, существует не менее $ \frac{p-1}{2} $ ``удачных'' выборов элемента $ \delta$, при которых на шаге 2 алгоритма многочлен $ f(x)$ распадется на два собственных множителя. Следовательно, при ``случайном'' выборе элемента $ \delta\in\FF_p$, вероятность того, что многочлен не разложится на множители после $ k$ повторений шагов алгоритма 1-4, не превосходит $ 2^{-k} $. Вероятность с ростом $ k$ убывает очень быстро. И действительно, на практике этот алгоритм работает достаточно эффективно.

    Заметим, что при оценке вероятности мы использовали только два корня многочлена $ f(x)$. При $ n>2$ эта вероятность, конечно, еще меньше. Более тонкий анализ с использованием оценок А. Вейля для сумм характеров показывает, что вероятность для многочлена $ f(x)$ не распасться на множители при однократном проходе шагов алгоритма 1-4, не превосходит $ 2^{-n}+O(p^{-1/2})$. Здесь постоянная в $ O(\cdot)$ зависит от $ n$. Детали доказательства см. в [24]. В настоящее время известно элементарное доказательство оценки А. Вейля (см. [9]).

    В книге [6] описывается принадлежащий Берлекэмпу детерминированный алгоритм решения сравнения (8), требующий $ O(pn^3) $ арифметических операций. Он практически бесполезен при больших $ p$, а вот при маленьких $ p$ и не очень больших $ n$ он работает не очень долго.

    Если в сравнении (8) заменить простой модуль $ p$ составным модулем $ m$, то задача нахождения решений соответствующего сравнения становится намного более сложной. Известные алгоритмы ее решения основаны на сведении сравнения к совокупности сравнений (8) по простым модулям - делителям $ m$, и, следовательно, они требуют разложения числа $ m$ на простые сомножители, что, как уже указывалось, является достаточно трудоемкой задачей.


    Next: 4.4. Как отличить составное Up: 4. Алгоритмические проблемы теории Previous: 4.2. Система шифрования RSA Contents: Содержание


    Проект осуществляется при поддержке:
    Геологического факультета МГУ,
    РФФИ
       

    TopList Rambler's Top100