Расширенный алгоритм Евклида — модификация алгоритма Евклида, вычисляющая, кроме наибольшего общего делителя (НОД) целых чисел и , ещё и коэффициенты соотношения Безу, то есть такие целые и , что
Алгоритм является , то есть помимо решения задачи приводит также доказательство корректности этого решения. Это связано с тем, что НОД является единственным числом, которое одновременно удовлетворяет уравнению и делит входные числа. Алгоритм позволяет также почти без дополнительных затрат вычислять частные от деления и на их наибольший общий делитель.
Под также понимается для вычисления наибольшего общего делителя многочленов и вычисления коэффициентов соотношения Безу двух многочленов от одной переменной.
Когда и взаимно просты, получаемый расширенным алгоритмом Евклида является модульным обратным числа по модулю , а является модульным обратным числа по модулю . Аналогично, расширенный алгоритм Евклида для многочленов позволяет вычислить обратное число в алгебраических расширениях и, в частности, в конечных полях непростого порядка. Поэтому оба расширенных алгоритма Евклида широко используются в криптографии. В частности, вычисление обратного элемента по модулю является существенным шагом в получении пары ключей в методе RSA шифрования с открытым ключом.
Описание Стандартный алгоритм Евклида выполняется путём последовательных делений с остатком, при этом частное не используется, и сохраняется только остаток. В расширенном алгоритме используются и частные от деления. Точнее, стандартный алгоритм Евклида для чисел и в качестве исходных данных состоит из вычисления последовательности частных и последовательности остатков, таких что:
Одним из свойств деления с остатком является то, что неравенство справа определяет единственность и для и .
Вычисление останавливается, когда достигaет нулевого остатка . Наибольший общий делитель тогда равен последнему ненулевому остатку .
Расширенный алгоритм Евклида вычисляет последовательности и аналогично, но добавляет ещё две последовательности и , вычисляемые следующим образом:
Вычисление останавливается, когда достигaет нулевого остатка (). Наибольший общий делитель тогда равен последнему ненулевому остатку . В итоге получаются искомые величины: равен наибольшему общему делителю входных значений и . Коэффициенты Безу равны и , то есть . Частные от деления и на их наибольший общий делитель задаются величинами и .
Более того, если оба числа и положительны и , то
для , где означает целую часть числа , то есть, наибольшее целое, не превосходящее .
Отсюда вытекает, что пара коэффициентов Безу, которую даёт расширенный алгоритм Евклида, является минимальной парой коэффициентов Безу, поскольку она является единственной парой, удовлетворяющей обоим неравенствам выше.
Также из этого следует, что алгоритм может быть выполнен без риска целочисленного переполнения программой, использующей целые числа фиксированного размера, который превосходит размер обоих чисел и .
Пример
Следующая таблица показывает, как расширенный алгоритм Евклида работает с входными числами и . Наибольший общий делитель — последний ненулевой элемент, в столбце «остаток». Вычисление завершается на строке 6, поскольку остаток в ней равен . Коэффициенты Безу появляются в двух последних ячейках предпоследней строки. Легко проверить, что . Наконец, два последних значения и последней строки, с точностью до знака, являются частными от деления входных значений и на наибольший общий делитель .
индекс i ti 0 0 1 1 2 ÷ = − × = − × = 0 − × 1 = −5 3 ÷ = − × = − × = 1 − × −5 = 21 4 ÷ = − × = − × = −5 − × 21 = −26 5 ÷ = − × = − × = 21 − × −26 = 6 ÷ = − × = − × = −26 − × 47 =
Доказательство Поскольку последовательность является строго убывающей последовательностью неотрицательных целых (начиная с i = 2). Тогда алгоритм должен остановиться на некотором Это доказывает, что алгоритм когда-нибудь завершится.
Поскольку наибольшие общие делители пар и одинаковы. По индукции можно показать, что наибольший общий делитель входных будет тем же самым, что и для , и таким образом доказать, что является наибольшим общим делителем a и b. (До этого момента доказательство то же самое, что и для классического алгоритма Евклида.)
Поскольку и , при i = 0 и 1 . Далее отношение доказывается по индукции для всех :
Тогда и являются коэффициентами Безу.
Рекуррентные соотношения можно переписать в матричном виде:
Матрица является единичной матрицей и её определитель равен единице. Определитель самой правой матрицы здесь равен −1. Отсюда следует, что определитель равен В частности, для определитель равен Если рассматривать это как соотношение Безу, получится, что и взаимно просты. Соотношение , доказанное выше, и лемма Евклида показывают, что делит , то есть для некоторого целого . При делении на соотношения получается Таким образом, и являются взаимно простыми целыми, которые являются частными от деления и на общий делитель, который является их наибольшим общим делителем или ему противоположным.
Последнее утверждение может быть доказано следующим образом: пусть a и b положительны и . Тогда , и если , то последовательности s и t для (a,b) в расширенном алгоритме являются, с точностью до начальных нулей и единиц, последовательностями t и s для (b,a). Определения затем показывают, что случай (a,b) сводится к случаю (b,a). Таким образом, без потери общности, можно предположить, что .
равно 1, а (которое существует ввиду ) отрицательно. Таким образом, меняет знак и строго возрастает по абсолютной величине, что следует по индукции из определения и факта, что для . Случай для выполняется, поскольку . То же самое верно для после нескольких первых членов по тем же причинам. Более того, (если a и b положительны и ). Тогда:
Это, и тот факт, что не меньше по абсолютному значению любого предыдущего или соответственно, завершает доказательство.
Расширение алгоритма Евклида для многочленов
Для многочленов от одной переменной с коэффициентами в поле всё работает аналогичным образом, включая деление Евклида, соотношение Безу и расширенный алгоритм Евклида. Первое отличие в том, что в делении Евклида и в алгоритме неравенство следует заменить на неравенство степеней Остальное остаётся тем же самым, просто заменяем целые числа многочленами.
Второе отличие лежит в границах размера коэффициентов Безу, даваемых расширенным алгоритмом Евклида, которые более точны в случае многочленов, что приводит к следующей теореме.
Если a и b два ненулевых многочлена, расширенный алгоритм Евклида даёт единственную пару многочленов (s, t), таких что
и
Третье отличие в том, что для многочленов наибольший общий делитель определён с точностью до умножения на ненулевую константу. Есть несколько путей определить наибольший общий делитель однозначно.
В математике обычно требуют, чтобы наибольший общий делитель был приведённым многочленом. Чтобы этого достичь, достаточно разделить все элементы результата на ведущий коэффициент Это позволяет, если a и b взаимно простые, получить 1 в правой части неравенства Безу. В противном случае получим ненулевую константу. В компьютерной алгебре многочлены обычно имеют целые коэффициенты и этот способ нормализации наибольшего общего делителя приводит к большому числу дробей.
Другим способом нормализации наибольшего общего делителя для случая целых коэффициентов является деление выходного многочлена на НОД коэффициентов многочлена , чтобы получить примитивный наибольший общий делитель. Если входные многочлены взаимно просты, нормализация даёт наибольший общий делитель, равный 1. Недостатком этого подхода является большое количество дробей, которые должны быть вычислены и упрощены.
Третий подход заключается в расширении алгоритма вычисления (подрезультантов) аналогично расширению алгоритма Евклида до расширенного алгоритма Евклида. Это позволяет, начав с многочлена с целыми коэффициентами, получать в процессе вычислений многочлены с целыми коэффициентами. Более того, каждый вычисленный остаток остаётся подрезультантом. В частности, если многочлены взаимно просты, то соотношение Безу превращается в
где означает результант для a и b. В таком виде соотношения Безу нет в формуле знаменателя. Если разделить всё на результант, получим классическое соотношение Безу с явным общим знаменателем для рациональных чисел которые при этом появляются.
Псевдокод
Для реализации вышеописанного алгоритма следует заметить, что только два последних значения индексированных переменных нужны на каждом шаге. Таким образом, для экономии памяти, каждая индексированная переменная должна быть заменена просто двумя переменными.
Для простоты следующий алгоритм (и другие алгоритмы в этой статье) используют параллельные присваивания. В языках программирования, не поддерживающих данную возможность параллельное присвоение необходимо осуществлять с использованием дополнительной переменной. Например, первое присвоение (old_r, r) := (r, old_r - quotient * r) эквивалентно prov := r; r := old_r - quotient × prov; old_r := prov; и аналогично для других параллельных присвоений. Это приводит к следующему коду:
function extended_gcd(a, b) (old_r, r) := (a, b) (old_s, s) := (1, 0) (old_t, t) := (0, 1)
while r ≠ 0 do quotient := old_r div r (old_r, r) := (r, old_r − quotient × r) (old_s, s) := (s, old_s − quotient × s) (old_t, t) := (t, old_t − quotient × t)
output "коэффициенты Безу:", (old_s, old_t) output "наибольший общий делитель:", old_r output "частные от деления на НОД:", (t, s)
Частные от деления a и b на их наибольший общий делитель, который тоже есть в выводе, могут иметь неверный знак. Это легко исправить в конце вычислений, но не сделано здесь для упрощения кода. Аналогично, если a или b равно нулю, а второе число отрицательно, наибольший общий делитель в выводе отрицателен, так что все знаки в выводе нужно изменить.
Наконец заметим, что соотношение Безу мoжно решить относительно при заданных . Тогда оптимизацией для алгоритма выше будет вычислять только последовательность (которая приводит к коэффициенту Безу ), а значение вычислить в конце алгоритма:
function extended_gcd(a, b) s := 0; old_s := 1 r := b; old_r := a
while r ≠ 0 do quotient := old_r div r (old_r, r) := (r, old_r − quotient × r) (old_s, s) := (s, old_s − quotient × s)
if b ≠ 0 then bezout_t := (old_r − old_s × a) div b else bezout_t := 0
output "коэффициенты Безу:", (old_s, bezout_t) output "наибольший общий делитель:", old_r
Однако, во многих случаях это не будет реальной оптимизацией — прежний алгоритм нечувствителен к переполнению при использовании целых чисел в машине (то есть целых чисел с фиксированной верхней границей представления), умножение old_s * a при вычислении bezout_t может вызвать переполнение, что ограничивает оптимизацию только на входные данные, которые не превосходят половины максимального размера целых чисел. Если используются целые числа неограниченного размера, время, необходимое для умножения и деления растёт квадратично от размера целых чисел. Из этого следует, что «оптимизация» заменяет последовательность умножений/делений малых чисел на одно умножение/деление, которое требует большего времени выполнения, чем операции, которые оно заменяет, взятые вместе.
Упрощение деления Деление находится в канонической упрощённой форме, если и взаимно просты и положительно. Эта каноническая упрощённая форма может быть получена путём замены трёх строк вывода на псеводокод if then output "Деление на ноль" if then ; (во избежание нулевых делителей) if then output (во избежание делителей, равных 1) output
Доказательство этого алгоритма полагается на факт, что и являются двумя взаимно простыми целыми, такими что , а тогда . Для получения канонически упрощённой формы достаточно изменить знак для получения положительного делителя.
Если делит нацело, алгоритм выполняет только одну итерацию, и мы имеем в конце алгоритма. Это единственный случай, когда вывод является целым числом.
Вычисление обратного в модулярных структурах