Алгоритм Берлекэмпа — Рабина

Материал из testwiki
Версия от 18:19, 4 июля 2023; imported>InternetArchiveBot (Спасено источников — 2, отмечено мёртвыми — 0. Сообщить об ошибке. См. FAQ.) #IABot (v2.0.9.5)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигации Перейти к поиску
Элвин Берлекэмп

Алгоритм Берлекэмпа — Рабина (также метод Берлекэмпа) — вероятностный метод нахождения корней многочленов над полем 𝔽pс полиномиальной сложностью. Метод был описан американским математиком Элвином Берлекэмпом в 1970 году[1] в качестве побочного к алгоритму факторизации многочленов над конечными полями и позже (в 1979 году) был доработан Михаэлем Рабином для случая произвольных конечных полей[2]. Изначальная версия алгоритма, предложенная Берлекэмпом в 1967 году[3], не была полиномиальной[4]. Опубликованная в 1970 году на основе результатов Шаблон:Не переведено 5 версия алгоритма работала с большими значениями p, в ней заглавный метод использовался в качестве вспомогательного[1]. На момент публикации метод был распространён в профессиональной среде, однако редко встречался в литературе[4].

История

Михаэль Ошер Рабин

Метод был предложен Элвином Берлекэмпом в его работе по факторизации многочленов над конечными полями[1]. В ней факторизация многочлена на неприводимые сомножители над полем 𝔽pk сводится к нахождению корней некоторых других многочленов над полем 𝔽p. При этом в оригинальной работе отсутствовало доказательство корректности алгоритма[2]. Алгоритм был доработан и обобщён на случай произвольных конечных полей Михаэлем Рабином[2]. В 1986 году Рене Перальта описал похожий алгоритм[5], решающий задачу нахождения квадратного корня в поле 𝔽p[6], а в 2000 году метод Перальты был обобщён для решения кубических уравнений[7].

В алгоритме Берлекэмпа многочлен f(x)=a0+a1x++anxn сперва представляется в виде произведения f(x)=h1(x)h2(x)hn(x), где hi — произведение ri многочленов степени i. Затем факторизация каждого такого многочлена hi(x) степени iri сводится к поиску корней нового многочлена H(x) степени ri. В статье, вводящей алгоритм факторизации, было также предложено три метода для поиска корней многочлена в поле Галуа 𝔽pk. Первые два сводят нахождение корней в поле 𝔽pk к поиску корней в поле 𝔽p. Третий метод, являющийся предметом данной статьи, решает задачу поиска корней в поле 𝔽p, что вместе с двумя другими решает задачу факторизации[1].

Версия алгоритма факторизации, предложенная Берлекэмпом в его первой работе в 1967 г.[3], работала за O(n3+prn), где r — количество неприводимых сомножителей многочлена. Таким образом, алгоритм являлся неполиномиальным и был непрактичным в случае, когда простое число p было достаточно большим. В 1969 г. эта проблема была решена Шаблон:Не переведено 5, показавшим, как свести узкое место алгоритма к задаче поиска корней некоторого многочлена[4]. В 1970 г. статья Берлекэмпа была переиздана уже с учётом решений Цассенхауза[1].

В 1980 г. Михаэль Рабин провёл строгий анализ алгоритма, обобщил его для работы с конечным полями вида 𝔽pk и доказал, что вероятность ошибки одной итерации алгоритма не превосходит 1/2[2], а в 1981 г. Михаэль Бен-Ор усилил эту оценку до 11/2k1+O(1/p), где k — количество различных корней многочлена f(x)[8]. Вопрос существования полиномиального детерминированного алгоритма для нахождения корней многочлена над конечным полем остаётся открытым — основные алгоритмы факторизации многочленов, алгоритм Берлекэмпа и Шаблон:Не переведено 5 являются вероятностными. В 1981 году Шаблон:Не переведено 5 показал[9], что такой алгоритм существует для любого наперёд заданного числа p, однако этот результат исключительно теоретический и вопрос о возможности построения описанных им множеств на практике остаётся открытым[10].

В первом издании второго тома «Искусства программирования» про получисленные алгоритмы Дональд Кнут пишет, что аналогичные процедуры факторизации были известны к 1960 г., однако редко встречались в открытом доступе[4]. Один из первых опубликованных примеров использования метода можно обнаружить в работе Голомба, Шаблон:Не переведено 5 и Шаблон:Не переведено 5 от 1959 года о факторизации трёхчленов над 𝔽2, где рассматривался частный случай p=2,z=1[11].

Алгоритм

Постановка задачи

Пусть p — нечётное простое число. Рассмотрим многочлен f(x)=a0+a1x++anxn над полем p остатков по модулю p. Необходимо найти все числа λ1,,λk такие что f(λi)0(modp) для всех возможных i[2][12].

Рандомизация

Пусть f(x)=(xλ1)(xλ2)(xλn). Нахождение всех корней такого многочлена равносильно его разбиению на линейные множители. Чтобы найти такое разбиение, достаточно научиться разбивать многочлен на любые два множителя, а затем запускаться в них рекурсивно. Для этого вводится в рассмотрение многочлен fz(x)=f(xz)=(xλ1z)(xλ2z)(xλnz), где z — случайное число из p. Если такой многочлен можно представить в виде произведения fz(x)=p0(x)p1(x), то в терминах исходного многочлена это значит, что f(x)=p0(x+z)p1(x+z), что даёт разбиение на множители исходного многочлена f(x)[1][12].

Классификация элементов 𝔽p

По критерию Эйлера для любого монома (xλ) выполнено ровно одно из следующих свойств[1]:

  1. Одночлен равен x, если λ=0,
  2. Одночлен делит g0(x)=(x(p1)/21), если λ — квадратичный вычет по модулю p,
  3. Одночлен делит g1(x)=(x(p1)/2+1), если λ — квадратичный невычет по этому модулю.

Таким образом, если fz(x) не делится на x, что можно проверить отдельно, то fz(x) равно произведению наибольших общих делителей gcd(fz(x);g0(x)) и gcd(fz(x);g1(x))[12].

Метод Берлекэмпа

Написанное выше приводит к следующему алгоритму[1]:

  1. В явном виде вычисляются коэффициенты многочлена fz(x)=f(xz),
  2. Вычисляются остатки от деления x,x2,x22,x23,x24,,x2log2p на fz(x) последовательным возведением в квадрат и взятием остатка от fz(x),
  3. Двоичным возведением в степень вычисляется остаток от деления x(p1)/2 на fz(x) с использованием посчитанных на прошлом шаге многочленов,
  4. Если x(p1)/2≢±1(modfz(x)), то указанные выше gcd дают нетривиальное разбиение fz(x) на множители,
  5. В противном случае все корни fz(x) являются вычетами или невычетами одновременно и стоит попробовать другое значения z.

Если f(x) также делится на некоторый многочлен g(x), не имеющий корней в p, то при подсчёте gcd с g0(x) и g1(x) будет получено разбиение бесквадратного многочлена fz(x)/gz(x) на нетривиальные сомножители, поэтому алгоритм позволяет найти все корни любых многочленов над p, а не только тех, которые разбиваются в произведение мономов[12].

Извлечение квадратного корня

Пусть нужно решить сравнение x2a(modp), решениями которого являются элементы β и β соответственно. Их нахождение эквивалентно факторизации многочлена f(x)=x2a=(xβ)(x+β) над полем p. В таком частном случае задача упрощается, так как для решения достаточно посчитать только gcd(fz(x);g0(x)). Для полученного многочлена будет верно ровно одно из утверждений:

  1. НОД равен 1, из чего следует, что z+β и zβ являются квадратичными невычетами одновременно,
  2. НОД равен fz(x), из чего следует, что оба числа являются квадратичными вычетами,
  3. НОД равен одночлену (xt), из чего следует, что ровно одно число из двух является квадратичным вычетом.

В третьем случае полученный одночлен должен быть равен или (xzβ), или (xz+β). Это позволяет записать решение в виде β=(tz)(modp)[1].

Пример

Пусть нужно решить сравнение x25(mod11). Для этого нужно факторизовать f(x)=x25=(xβ)(x+β). Рассмотрим возможные значения z:

  1. Пусть z=3. Тогда fz(x)=(x3)25=x26x+4, откуда gcd(x26x+4;x51)=1. Оба числа 3±β являются невычетами и нужно брать другое z.
  1. Пусть z=2. Тогда fz(x)=(x2)25=x24x1, откуда gcd(x24x1;x51)x9(mod11). Отсюда x9=x2β, значит β7(mod11) и β74(mod11).

Проверка показывает, что действительно 72495(mod11) и 42165(mod11).

Обоснование метода

Алгоритм находит разбиение fz(x) на нетривиальные множители во всех случаях, за исключением тех, в которых все числа z+λ1,z+λ2,,z+λn являются вычетами или невычетами одновременно. Согласно теории циклотомии[1], вероятность такого события для случая, когда λ1,,λn сами одновременно являются вычетами или невычетами одновременно (то есть, когда z=0 не подходит для нашей процедуры), можно оценить как 1/2k1[8], где k — количество различных чисел среди λ1,,λn[1]. Таким образом, вероятность ошибки алгоритма не превосходит 1/2.

Применение к факторизации многочленов

Шаблон:Основная статья Из теории конечных полей известно, что если степень неприводимого многочлена q(x) равна d, то такой многочлен является делителем xpdx и не является делителем xptx для t<d.

Таким образом, последовательно рассматривая многочлены hi(x)=gcd(fi(x),xpi1) где f1(x)=f(x) и fi(x)=fi1(x)/hi1(x) для i>1, можно разбить многочлен f(x) на множители вида f(x)=h1(x)hn(x), где hi(x) — это произведение всех неприводимых многочленов степени i, которые делят многочлен f(x). Зная степень hi(x), можно определить количество таких многочленов, равное ri=deghi(x)/i. Пусть hi(x)=p1(x)pri(x). Если рассмотреть многочлен pj(xz), где z𝔽p, то порядок такого многочлена dj в поле 𝔽pi должен делить число pi1. Если dj не делится на dk, то многочлен xdjx делится на pj(xz), но не на pk(xz).

Исходя из этого Шаблон:Не переведено 5 предложил искать делители многочлена hi(xz) в виде gcd(hi(xz),xf1), где f — некоторый достаточно большой делитель pi1, например, f=pi12. В частном случае i=1 получается в точности метод Берлекэмпа как он описан выше[4].

Время работы

Поэтапно время работы одной итерации алгоритма можно оценить следующим образом, считая степень многочлена равной n:

  1. Учитывая, что (xz)k=i=0k(ki)(z)kixi по формуле бинома Ньютона, переход от f(x) к f(xz) делается за O(n2),
  2. Произведение многочленов и взятие остатка от одного многочлена по модулю другого делается за O(n2), поэтому вычисление x2kmodfz(x) делается за O(n2logp),
  3. Аналогично предыдущему пункту, двоичное возведение в степень делается за O(n2logp),
  4. Взятие gcd от двух многочленов по алгоритму Евклида делается за O(n2).

Таким образом, одна итерация алгоритма может быть произведена за O(n2logp) арифметических операций с элементами 𝔽p, а нахождение всех корней многочлена требует в среднем O(n2lognlogp)[8]. В частном случае извлечения квадратного корня величина n равна двум, поэтому время работы оценивается как O(logp) на одну итерацию алгоритма[12].

Примечания

Шаблон:Примечания

Шаблон:Теоретико-числовые алгоритмы Шаблон:Добротная статья