Jump to content

Бинарный алгоритм НОД

Визуализация использования алгоритма двоичного НОД для поиска наибольшего общего делителя (НОД) чисел 36 и 24. Таким образом, НОД равен 2. 2 × 3 = 12.

Бинарный алгоритм НОД , также известный как алгоритм Штейна или бинарный алгоритм Евклида , [1] [2] — это алгоритм, который вычисляет наибольший общий делитель (НОД) двух неотрицательных целых чисел. Алгоритм Штейна использует более простые арифметические операции, чем обычный алгоритм Евклида ; он заменяет деление арифметическими сдвигами , сравнениями и вычитанием.

Хотя алгоритм в его современном виде был впервые опубликован израильским физиком и программистом Йозефом Штейном в 1967 году. [3] возможно, он был известен во II веке до нашей эры в древнем Китае. [4]

Алгоритм

[ редактировать ]

Алгоритм находит НОД двух неотрицательных чисел. и неоднократно применяя эти тождества:

  1. : все делит ноль, и самое большое число, которое делит .
  2. : является общим делителем.
  3. если странно: тогда не является общим делителем.
  4. если странный и .

Поскольку НОД коммутативен ( ), эти идентификаторы по-прежнему применяются, если операнды поменяны местами: , если это странно и т. д.

Выполнение

[ редактировать ]

Хотя приведенное выше описание алгоритма математически корректно, производительные программные реализации обычно отличаются от него по нескольким заметным признакам:

  • избегая пробного деления на в пользу одного битового сдвига и примитива подсчета конечных нулей ; это функционально эквивалентно многократному применению тождества 3, но гораздо быстрее;
  • выражение алгоритма итеративно, а не рекурсивно : результирующую реализацию можно спланировать так, чтобы избежать повторной работы, вызывая идентификатор 2 в начале и сохраняя инвариантом то, что оба числа нечетны при входе в цикл, который должен реализовать только идентификаторы 3 и 4;
  • делая тело цикла свободным от ветвей, за исключением условия выхода ( ): в приведенном ниже примере обмен и (обеспечение ) компилируется в условные ходы ; [5] труднопрогнозируемые ветки могут оказать большое негативное влияние на производительность. [6] [7]

Ниже приведена реализация алгоритма на Rust, иллюстрирующая эти различия, адаптированная из uutils :

use std::cmp::min;
use std::mem::swap;

pub fn gcd(mut u: u64, mut v: u64) -> u64 {
    // Base cases: gcd(n, 0) = gcd(0, n) = n
    if u == 0 {
        return v;
    } else if v == 0 {
        return u;
    }

    // Using identities 2 and 3:
    // gcd(2ⁱ u, 2ʲ v) = 2ᵏ gcd(u, v) with u, v odd and k = min(i, j)
    // 2ᵏ is the greatest power of two that divides both 2ⁱ u and 2ʲ v
    let i = u.trailing_zeros();  u >>= i;
    let j = v.trailing_zeros();  v >>= j;
    let k = min(i, j);

    loop {
        // u and v are odd at the start of the loop
        debug_assert!(u % 2 == 1, "u = {} should be odd", u);
        debug_assert!(v % 2 == 1, "v = {} should be odd", v);

        // Swap if necessary so u ≤ v
        if u > v {
            swap(&mut u, &mut v);
        }

        // Identity 4: gcd(u, v) = gcd(u, v-u) as u ≤ v and u, v are both odd 
        v -= u;
        // v is now even

        if v == 0 {
            // Identity 1: gcd(u, 0) = u
            // The shift by k is necessary to add back the 2ᵏ factor that was removed before the loop
            return u << k;
        }

        // Identity 3: gcd(u, 2ʲ v) = gcd(u, v) as u is odd
        v >>= v.trailing_zeros();
    }
}

информация Примечание. Приведенная выше реализация принимает беззнаковые (неотрицательные) целые числа; при условии , подписанный случай можно обработать следующим образом:

/// Computes the GCD of two signed 64-bit integers
/// The result is unsigned and not always representable as i64: gcd(i64::MIN, i64::MIN) == 1 << 63
pub fn signed_gcd(u: i64, v: i64) -> u64 {
    gcd(u.unsigned_abs(), v.unsigned_abs())
}

Сложность

[ редактировать ]

Асимптотически алгоритм требует шаги, где - это количество битов в большем из двух чисел, поскольку каждые два шага уменьшают хотя бы один из операндов как минимум в раз. . Каждый шаг включает в себя всего несколько арифметических операций ( с небольшой константой); при работе с числами размером в слово каждая арифметическая операция преобразуется в одну машинную операцию, поэтому количество машинных операций порядка , то есть .

Для сколь угодно больших чисел асимптотическая сложность этого алгоритма равна , [8] поскольку каждая арифметическая операция (вычитание и сдвиг) включает в себя линейное количество машинных операций (по одной на слово в двоичном представлении чисел). Если числа могут быть представлены в памяти машины, т. е. каждого числа размер может быть представлен одним машинным словом, эта граница сводится к:

Это то же самое, что и для алгоритма Евклида, хотя более точный анализ Ахави и Валле показал, что двоичный НОД использует примерно на 60% меньше битовых операций. [9]

Расширения

[ редактировать ]

Алгоритм двоичного НОД можно расширить несколькими способами: либо для вывода дополнительной информации, более эффективной работы с целыми числами произвольного размера , либо для вычисления НОД в областях, отличных от целых чисел.

Расширенный двоичный алгоритм НОД , аналог расширенного алгоритма Евклида , подходит для первого типа расширения, поскольку он предоставляет коэффициенты Безу : целые числа. в дополнение к НОД и такой, что . [10] [11] [12]

В случае больших целых чисел лучшая асимптотическая сложность равна , с стоимость -битовое умножение; это почти линейно и значительно меньше, чем алгоритм двоичного НОД. , хотя конкретные реализации превосходят старые алгоритмы только для чисел размером более 64 килобит ( т. е. более 8×10 19265 ). Это достигается за счет расширения двоичного алгоритма НОД с использованием идей алгоритма Шёнхаге – Штрассена для быстрого умножения целых чисел. [13]

Алгоритм двоичного НОД также был распространен на области, отличные от натуральных чисел, такие как целые гауссовы числа . [14] Целые числа Эйзенштейна , [15] квадратичные кольца, [16] [17] и целочисленные кольца числовых полей . [18]

Историческое описание

[ редактировать ]

Алгоритм вычисления НОД двух чисел был известен в древнем Китае, при династии Хань , как метод сокращения дробей:

Если возможно, сократите его вдвое; в противном случае возьмите знаменатель и числитель, вычтите меньшее из большего и сделайте это поочередно, чтобы они стали одинаковыми. Уменьшите на такое же количество.

- Фангтянь - Землеустройство, Девять глав математического искусства

Фраза «если возможно, сократите вдвое» двусмысленна, [4]

  • если это применимо, когда любое из чисел становится четным, алгоритм представляет собой двоичный алгоритм НОД;
  • если это применимо только тогда, когда оба числа четные, алгоритм аналогичен алгоритму Евклида .

См. также

[ редактировать ]
  1. ^ Брент, Ричард П. (13–15 сентября 1999 г.). Двадцатилетний анализ двоичного алгоритма Евклида . 1999 Симпозиум Оксфорд-Майкрософт в честь профессора сэра Энтони Хоара. Оксфорд.
  2. ^ Брент, Ричард П. (ноябрь 1999 г.). Дальнейший анализ Бинарного алгоритма Евклида (Технический отчет). Вычислительная лаборатория Оксфордского университета. arXiv : 1303.2772 . ПРГ ТР-7-99.
  3. ^ Стейн, Дж. (февраль 1967 г.), «Вычислительные проблемы, связанные с алгеброй Рака», Журнал вычислительной физики , 1 (3): 397–405, Бибкод : 1967JCoPh...1..397S , doi : 10.1016/0021-9991 (67)90047-2 , ISSN   0021-9991
  4. Перейти обратно: Перейти обратно: а б Кнут, Дональд (1998), Получисловые алгоритмы , Искусство компьютерного программирования , том. 2 (3-е изд.), Аддисон-Уэсли, ISBN  978-0-201-89684-8
  5. ^ Годболт, Мэтт. «Проводник компиляторов» . Проверено 4 февраля 2024 г.
  6. ^ Капур, Раджив (21 февраля 2009 г.). «Как избежать стоимости неверного прогноза ветвей» . Зона разработчиков Intel .
  7. ^ Лемир, Дэниел (15 октября 2019 г.). «Неправильно предсказанные ветки могут увеличить время работы» .
  8. ^ «GNU MP 6.1.2: Двоичный НОД» .
  9. ^ Ахави, Али; Валле, Бриджит (2000), «Средняя битовая сложность евклидовых алгоритмов» , Proceedings ICALP'00, Конспекты лекций Computer Science 1853 : 373–387, CiteSeerX   10.1.1.42.7616
  10. ^ Кнут 1998 , с. 646, ответ к упражнению 39 раздела 4.5.2.
  11. ^ Менезес, Альфред Дж.; ван Оршот, Пол К.; Ванстон, Скотт А. (октябрь 1996 г.). «§14.4 Алгоритмы наибольшего общего делителя» (PDF) . Справочник по прикладной криптографии . ЦРК Пресс. стр. 606–610. ISBN  0-8493-8523-7 . Проверено 9 сентября 2017 г.
  12. ^ Коэн, Анри (1993). «Глава 1: Фундаментальные теоретико-числовые алгоритмы». Курс вычислительной алгебраической теории чисел . Тексты для аспирантов по математике . Том. 138. Шпрингер-Верлаг . стр. 17–18. ISBN  0-387-55640-0 .
  13. ^ Стеле, Дэмиен; Циммерманн, Пол (2004), «Двоичный рекурсивный алгоритм НОД» (PDF) , Алгоритмическая теория чисел , Конспекты лекций по Comput. наук, том. 3076, Springer, Берлин, стр. 411–425, CiteSeerX   10.1.1.107.8612 , doi : 10.1007/978-3-540-24847-7_31 , ISBN  978-3-540-22156-2 , MR   2138011 , S2CID   3119374 , Отчет об исследованиях INRIA RR-5050 .
  14. ^ Вейлерт, Андре (июль 2000 г.). «(1+i)-арное вычисление НОД в Z[i] как аналог алгоритма двоичного НОД» . Журнал символических вычислений . 30 (5): 605–617. дои : 10.1006/jsco.2000.0422 .
  15. ^ Дамгорд, Иван Бьерре; Франдсен, Гудмунд Сковбьерг (12–15 августа 2003 г.). Эффективные алгоритмы определения НОД и кубической невязки в кольце целых чисел Эйзенштейна . 14-й Международный симпозиум по основам теории вычислений. Мальмё , Швеция. стр. 109–117. дои : 10.1007/978-3-540-45077-1_11 .
  16. ^ Агарвал, Саураб; Франдсен, Гудмунд Сковбьерг (13–18 июня 2004 г.). Бинарный НОД-подобные алгоритмы для некоторых комплексных квадратичных колец . Симпозиум по алгоритмической теории чисел. Берлингтон, Вирджиния , США. стр. 57–71. дои : 10.1007/978-3-540-24847-7_4 .
  17. ^ Агарвал, Саураб; Франдсен, Гудмунд Сковбьерг (20–24 марта 2006 г.). Новый алгоритм НОД для колец квадратичных чисел с уникальной факторизацией . 7-й Латиноамериканский симпозиум по теоретической информатике. Вальдивия, Чили. стр. 30–42. дои : 10.1007/11682462_8 .
  18. ^ Викстрем, Дуглас (11–15 июля 2005 г.). Об l-арном НОД-алгоритме в кольцах целых чисел . Автоматы, языки и программирование, 32-й международный коллоквиум. Лиссабон, Португалия. стр. 1189–1201. дои : 10.1007/11523468_96 .

Дальнейшее чтение

[ редактировать ]

Охватывает расширенный двоичный НОД и вероятностный анализ алгоритма.

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

Анализ алгоритма в среднем случае через призму функционального анализа : основные параметры алгоритмов представлены как динамическая система , а их среднее значение связано с инвариантной мерой системы передаточного оператора .

[ редактировать ]


Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: a65fb696553a48ff0cf10363ac4c5285__1719649200
URL1:https://arc.ask3.ru/arc/aa/a6/85/a65fb696553a48ff0cf10363ac4c5285.html
Заголовок, (Title) документа по адресу, URL1:
Binary GCD algorithm - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)