Расширенный алгоритм Евклида

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Расширенный алгоритм Евклида
Названо в честь Евклид

Расширенный алгоритм Евклида — модификация алгоритма Евклида, вычисляющая, кроме наибольшего общего делителя (НОД) целых чисел и , ещё и коэффициенты соотношения Безу, то есть такие целые и , что

Алгоритм является удостоверяющим[англ.], то есть помимо решения задачи приводит также доказательство корректности этого решения. Это связано с тем, что НОД является единственным числом, которое одновременно удовлетворяет уравнению и делит входные числа. Алгоритм позволяет также почти без дополнительных затрат вычислять частные от деления и на их наибольший общий делитель.

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

Когда и взаимно просты, получаемый расширенным алгоритмом Евклида является модульным обратным числа по модулю , а является модульным обратным числа по модулю . Аналогично, расширенный алгоритм Евклида для многочленов позволяет вычислить обратное число в алгебраических расширениях и, в частности, в конечных полях непростого порядка. Поэтому оба расширенных алгоритма Евклида широко используются в криптографии. В частности, вычисление обратного элемента по модулю является существенным шагом в получении пары ключей в методе RSA шифрования с открытым ключом.

Описание[править | править код]

Стандартный алгоритм Евклида выполняется путём последовательных делений с остатком, при этом частное не используется, и сохраняется только остаток. В расширенном алгоритме используются и частные от деления. Точнее, стандартный алгоритм Евклида для чисел и в качестве исходных данных состоит из вычисления последовательности частных и последовательности остатков, таких что:

Одним из свойств деления с остатком является то, что неравенство справа определяет единственность и для и .

Вычисление останавливается, когда достигaет нулевого остатка . Наибольший общий делитель тогда равен последнему ненулевому остатку .

Расширенный алгоритм Евклида вычисляет последовательности и аналогично, но добавляет ещё две последовательности и , вычисляемые следующим образом:

Вычисление останавливается, когда . В итоге получаются искомые величины:

  • равен наибольшему общему делителю входных значений и .
  • Коэффициенты Безу равны и , то есть .
  • Частные от деления и на их наибольший общий делитель задаются величинами и .

Более того, если оба числа и положительны и , то

для , где означает целую часть числа , то есть, наибольшее целое, не превосходящее .

Отсюда вытекает, что пара коэффициентов Безу, которую даёт расширенный алгоритм Евклида, является минимальной парой коэффициентов Безу, поскольку она является единственной парой, удовлетворяющей обоим неравенствам выше.

Также из этого следует, что алгоритм может быть выполнен без риска целочисленного переполнения программой, использующей целые числа фиксированного размера, который превосходит размер обоих чисел и .

Пример[править | править код]

Следующая таблица показывает, как расширенный алгоритм Евклида работает с входными числами 240 и 46. Наибольший общий делитель — последний ненулевой элемент, 2 в столбце «остаток». Вычисление завершается на строке 6, поскольку остаток в ней равен 0. Коэффициенты Безу появляются в двух последних ячейках предпоследней строки. Легко проверить, что −9 × 240 + 47 × 46 = 2. Наконец, два последних значения 23 и −120 последней строки, с точностью до знака, являются частными от деления входных значений 46 и 240 на наибольший общий делитель 2.

индекс i частное qi−1 остаток ri si ti
0 240 1 0
1 46 0 1
2 240 ÷ 46 = 5 2405 × 46 = 10 15 × 0 = 1 0 − 5 × 1 = −5
3 46 ÷ 10 = 4 464 × 10 = 6 04 × 1 = −4 1 − 4 × −5 = 21
4 10 ÷ 6 = 1 101 × 6 = 4 11 × −4 = 5 −5 − 1 × 21 = −26
5 6 ÷ 4 = 1 61 × 4 = 2 −41 × 5 = −9 21 − 1 × −26 = 47
6 4 ÷ 2 = 2 42 × 2 = 0 52 × −9 = 23 −26 − 2 × 47 = −120

Доказательство[править | править код]

Поскольку последовательность является строго убывающей последовательностью неотрицательных целых (начиная с i = 2). Тогда алгоритм должен остановиться на некотором Это доказывает, что алгоритм когда-нибудь завершится.

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

Поскольку и , при i = 0 и 1 . Далее отношение доказывается по индукции для всех :

Тогда и являются коэффициентами Безу.

Рекуррентные соотношения можно переписать в матричном виде:

Матрица является единичной матрицей и её определитель равен единице. Определитель самой правой матрицы здесь равен −1. Отсюда следует, что определитель равен В частности, для определитель равен Если рассматривать это как соотношение Безу, получится, что и взаимно просты. Соотношение , доказанное выше, и лемма Евклида показывают, что делит b, то есть для некоторого целого d. При делении на соотношения получается Таким образом, и являются взаимно простыми целыми, которые являются частными от деления a и b на общий делитель, который является их наибольшим общим делителем или ему противоположным.

Последнее утверждение может быть доказано следующим образом: пусть 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 может вызвать переполнение, что ограничивает оптимизацию только на входные данные, которые не превосходят половины максимального размера целых чисел. Если используются целые числа неограниченного размера, время, необходимое для умножения и деления растёт квадратично от размера целых чисел. Из этого следует, что «оптимизация» заменяет последовательность умножений/делений малых чисел на одно умножение/деление, которое требует большего времени выполнения, чем операции, которые оно заменяет, взятые вместе.

Упрощение деления[править | править код]

Деление a/b находится в канонической упрощённой форме, если a и b взаимно просты и b положительно. Эта каноническая упрощённая форма может быть получена путём замены трёх строк вывода на псеводокод

if s = 0 then output "Деление на ноль"
if s < 0 then s := −s;  t := −t   (во избежание нулевых делителей)
if s = 1 then output -t        (во избежание делителей, равных  1)
output -t/s

Доказательство этого алгоритма полагается на факт, что s и t являются двумя взаимно простыми целыми, такими что , а тогда . Для получения канонически упрощённой формы достаточно изменить знак для получения положительного делителя.

Если b делит a нацело, алгоритм выполняет только одну итерацию, и мы имеем s = 1 в конце алгоритма. Это единственный случай, когда вывод является целым числом.

Вычисление обратного в модулярных структурах[править | править код]

Расширенный алгоритм Евклида является важным средством вычисления обратных чисел в модулярных структурах, обычно в модулярных целых и алгебраических расширениях полей. Важным примером последнего случая являются конечные поля непростого порядка.

Целые по модулю[править | править код]

Если n является положительным целым, кольцо Z/nZ может быть отождествлено со множеством {0, 1, ..., n-1} остатков от деления с остатком на n, сложение и умножение заключается во взятии остатка от деления на n результатов сложения и умножения целых чисел. Элемент a Z/nZ имеет обратный элемент (то есть элемент обратимый), если он взаимно прост с n. В частности, если n является простым, a имеет обратное, если оно не нулевое (по модулю n). То есть, Z/nZ будет полем тогда и только тогда, когда n просто.

Соотношение Безу утверждает, что a и n взаимно просты тогда и только тогда, когда существуют целые sи t, такие что

Сравнение по модулю n даёт

Тогда t, или точнее, остаток от деления t на n, равен обратному числу a по модулю n.

Чтобы приспособить расширенный алгоритм Евклида для этой задачи, следует заметить, что коэффициент Безу при n не нужен, а потому нет необходимости его и вычислять. Также, для получения результата в виде положительного числа, меньшего n, можно использовать факт что целое t, предоставляемое алгоритмом, удовлетворяет соотношению . То есть, если , можно добавить n в конце. Это приводит к псевдокоду, в котором входное значение n является целым, большим 1.

 function inverse(a, n)
    t := 0;     newt := 1
    r := n;     newr := a

    while newr ≠ 0 do
        quotient := r div newr
        (t, newt) := (newt, t − quotient × newt) 
        (r, newr) := (newr, r − quotient × newr)

    if r > 1 then
        return "не обратимо"
    if t < 0 then
        t := t + n

    return t

Алгебраические расширения полей[править | править код]

Расширенный алгоритм Евклида является также главным средством для вычисления обратных элементов в алгебраических расширениях полей. Важный случай, широко используемый в криптографии и теории кодирования, это случай конечных полей непростого порядка. Фактически, если p просто и q = pd, поле порядка q является алгебраическим расширением простого поля с p элементами, образованного корнем неприводимого многочлена степени d.

Алгебраическое расширение L поля K, генерируемое корнем неприводимого многочлена p степени d можно отождествить с факторкольцом , а его элементы находятся в биективном соотношении с многочленами степени, меньшей d.Сложениев L есть сложение многочленов. Умножение в L есть остаток от деления с остатком[англ.]на p произведения многочленов. Таким образом, для завершения арифметики в L остаётся только определить, каким образом вычислять обратные элементы. Делается это с расширенным алгоритмом Евклида.

Алгоритм очень похож на приведённый выше для вычисления модульного обратного. Есть два главных отличия — во-первых, предпоследняя строка не нужна, поскольку получаемые коэффициенты Безу имеют всегда степень меньшую, чем d. Во-вторых, Наибольший общий делитель, который получается, если входные данные являются взаимно простыми многочленами, может быть любым ненулевым элементом K. Этот коэффициент Безу (многочлен обычно имеет положительную степень), следует умножить на обратный этому элементу в K. В псевдокоде (ниже) p является многочленом степени, большим единицы, а a является многочленом.

function inverse(a, p)
    t := 0;     newt := 1
    r := p;     newr := a

    while newr ≠ 0 do
        quotient := r div newr
        (r, newr) := (newr, r − quotient × newr)
        (t, newt) := (newt, t − quotient × newt)

    if degree(r) > 0 then 
        return "Either p is not irreducible or a is a multiple of p"

    return (1/r) × t

Пример[править | править код]

Например, пусть многочлен определяет конечное поле , а является элементом, обратный которому нужно найти. Тогда работа алгоритма приведена ниже в таблице. Напомни, что в поле порядка , имеем -z = z и z + z = 0 для любого или элемента z поля). Поскольку 1 является единственным ненулевым элементом GF(2), подгонка последней строки псевдокода не нужна.

шаг  частное  r, newr s, news t, newt
  1  0
  0  1
1 1
2
3  x + 1
4  x + 1  

Таким образом, обратный элемент равен , что подтверждается умножением двух элементов[англ.] и взятия остатка по p от результата.

Случай более двух чисел[править | править код]

Можно обрабатывать случай более двух чисел итеративно. Сначала покажем, что . Для доказательства положим . По определению НОД является делителем и . Тогда для некоторого . Аналогично является делителем , так что для некоторого . Положим . По построению , , но поскольку является наибольшим делителем, является обратимым элементом. А поскольку , результат доказан.

Таким образом, если , то есть и , такие что , так что конечным уравнением будет

Для перехода к n числам используем индукцию

См. также[править | править код]

Примечания[править | править код]

Литература[править | править код]

  • Donald Knuth. Chapter 4 // The Art of Computer Programming. — Addison-Wesley. — Т. 2..
    • Перевод Дональд Кнут. Искусство программирования. — 1998. — Т. 2. Получисленные алгоритмы.
  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein. section 31.2: Greatest common divisor. // Introduction to Algorithms. — Second Edition. — MIT Press and McGraw-Hill, 2001. — С. 859–861. — ISBN 0-262-03293-7.

Ссылки[править | править код]