КУРС «ТЕОРИЯ АЛГОРИТМОВ». КРАТКИЕ ОТВЕТЫ НА ЭКЗАМЕНАЦИОННЫЕ ВОПРОСЫ - 1 Александр Павлов Руководитель группы подготовки и проведения тренингов https://academy.kaspersky.ru/ ; https://securelist.ru/ СПИСОК ЛИТЕРАТУРЫ 1. В.И.Игошин «Теория алгоритмов». 2013. 2. Стивен Скиена «Алгоритмы. Руководство по разработке». 2014. 3. С. Дасгупта, Х. Пападимитриу, У. Вазирани «Алгоритмы». 2014. 4. Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн «Алгоритмы. Построение и анализ». 2013. 5. Дж. Прескилл «Квантовая информация и квантовые вычисления. Том 1». 2008. 6. С. Панасенко «Алгоритмы шифрования», 2008. 3 7. Под ред. В.В.Ященко «Ведение в криптографию», 2000. 8. Н.С.Бахвалов, Н.П.Жидков, Г.М.Кобельков «Численные методы». 1987. 9. Ю.В.Нестеренко «Теория чисел», 2008. 10. О.Н.Василенко «Теоретико-числовые алгоритмы в криптографии», 2006. 11. М.П.Минеев, В.Н.Чубариков, «Лекции по арифметическим вопросам криптографии», 2014. 12. В.И.Крупский, В.Е.Плиско «Математическая логика и теория алгоритмов». 2013. 13. Н.П.Редькин «Дискретная математика», 2009. 4 14. Alfred J. Menezes, Paul C. van Oorschot, Scott A. Vanstone, “Handbook of Applied Cryptography”, 2014. 15. Myasnikov A., Shpilrain V., Ushakov A., “Group-based Cryptography”, 2008. 5 1. АЛГОРИТМ ЕВКЛИДА АЛГОРИТМ ЕВКЛИДА Самый известный алгоритм древности. Изложен в книге «Начала» (III в. до н.э.). Чтобы найти 𝑛, 𝑚 , надо поступить следующим образом: 𝑛 = 𝑚𝑞0 + 𝑟1 𝑚 = 𝑟1 𝑞1 + 𝑟2 𝑟1 = 𝑟2 𝑞2 + 𝑟3 … 𝑟𝑡−2 = 𝑟𝑡−1 𝑞𝑡−1 + 𝑟𝑡 𝑟𝑡−1 = 𝑟𝑡 𝑞𝑡 Тогда 𝑛, 𝑚 = 𝑟𝑡 . 7 РЕКУРСИВНЫЙ АЛГОРИТМ ЕВКЛИДА Лемма. 𝑎, 𝑏 = 𝑏, 𝑎 mod 𝑏 Лемма. Если 𝑎 ≥ 𝑏, то 𝑎 mod 𝑏 < 𝑎/2. Euclid (a,b) Вход: целые числа 𝑎 ≥ 𝑏 ≥ 0. Выход: 𝑎, 𝑏 Если 𝑏 = 0: вернуть 𝑎. Вернуть Euclid (b, a mod b). Сложность алгоритма. По лемме после двух вызовов длина каждого из чисел 𝑎, 𝑏 уменьшится хотя бы вдвое, то есть уменьшится хотя бы на 1 бит. Таким образом, потребуется не более 2𝑛 вызовов, на каждом из которых производим деление за время 𝑂 𝑛2 . Следовательно, 𝑇 𝑛 = 𝑂 𝑛3 . 8 РАСШИРЕННЫЙ АЛГОРИТМ ЕВКЛИДА Лемма. Если 𝑑 делит оба числа 𝑎, 𝑏, а также 𝑑 = 𝑎𝑥 + 𝑏𝑦 для некоторых целых чисел 𝑥, 𝑦, то 𝑑 = 𝑎, 𝑏 . ExtendedEuclid (a,b) Вход: целые числа 𝑎 ≥ 𝑏 ≥ 0. Выход: целые числа 𝑥, 𝑦, 𝑑, для которых 𝑑 = 𝑎, 𝑏 и 𝑎𝑥 + 𝑏𝑦 = 𝑑. Если 𝑏 = 0: вернуть 1,0, 𝑎 . 𝑥 ′ , 𝑦 ′ , 𝑑 ←ExtendedEuclid (b, a mod b) вернуть (𝑦 ′ , 𝑥 ′ − 𝑎 𝑏 𝑦 ′ , 𝑑) Сложность алгоритма. 𝑇 𝑛 = 𝑂 𝑛3 . 9 2. ПРИМЕРЫ ВЫЧИСЛЕНИЕ ЧИСЕЛ ФИБОНАЧЧИ: АЛГОРИТМ FIB1 𝑓1 = 𝑓2 = 1, 𝑓𝑛 = 𝑓𝑛−1 + 𝑓𝑛−2 для 𝑛 ≥ 3. Рекурсивный алгоритм Fib1(𝑛). 1. Ввод 𝑛. 2. Если n = 1, вернуть 1 и конец программы. 3. Если n = 2, вернуть 1 и конец программы. 4. Вернуть Fib1 𝑛 − 1 + Fib1 𝑛 − 2 . 11 ВЫЧИСЛЕНИЕ ЧИСЕЛ ФИБОНАЧЧИ: АЛГОРИТМ FIB2 Алгоритм Fib2 𝑛 . 1. Ввод 𝑛. 2.f 1 ≔ 1, 𝑓 2 ≔ 1. 3. Если n = 1, вернуть 1 и конец программы. 4. Если n = 2, вернуть 1 и конец программы. 5. Для 𝑖 от 3 до 𝑛 𝑓 𝑖 ≔𝑓 𝑖−1 +𝑓 𝑖−2 6. Вывод 𝑓 𝑛 . 12 СЛОЖНОСТЬ АЛГОРИТМОВ FIB1 И FIB2 Алгоритм Fib1: 𝑇 𝑛 = 𝑇 𝑛 − 1 + 𝑇(𝑛 − 2). Следовательно, скорость роста экспоненциальная. Такой алгоритм практически бесполезен на практике. Например: для вычисления 𝑓200 понадобится около 2138 операций. На это суперкомпьютеру с вычислительной мощностью 10 терафлопс (1013 операций в секунду) понадобится около 295 секунд. (Проверьте!) Это порядка 1021 лет. В то время как возраст Вселенной «всего» 14 ⋅ 109 лет. Алгоритм Fib2: 𝑇 𝑛 = 𝑂 𝑛 . Полиномиальное (линейное) время работы. Теперь 𝑓200 и даже 𝑓2000000 вычисляется без труда. 13 Определение. Пусть E – ограниченное самоподобное подмножество пространства ℝn (относительно коэффициента r и натурального числа N). Размерностью подобия DS множества E назовем величину ln N DS E = ln 𝑟 Определение. Фракталом называется самоподобное ограниченное подмножество метрического пространства. 14 Алгоритм: построение фракталов Вход: базовый элемент (с точностью до масштаба); фигура 𝐹0 нулевого шага, представленная как дизъюнктное объединение базовых элементов; число итераций 𝑁. Выход: Фигура 𝐹𝑁 - приближение к фракталу после 𝑁 итераций. 𝑛 ≔ 1; Пока 𝑛 ≤ 𝑁 { Строим фигуру 𝐹𝑛 𝑛-ой итерации. Для этого каждый базовый элемент фигуры 𝐹𝑛−1 заменяем на фигуру 𝐹0 (с учетом масштаба). Обновляем набор базовых элементов для 𝑛-го шага, из которых состоит фигура 𝐹𝑛 . 𝑛 ≔ 𝑛 + 1; } 15 3. ГРАНИЦЫ РАЦИОНАЛЬНОГО ПОЗНАНИЯ ETC. Курт Гёдель (1906 - 1978). Первая теорема о неполноте. Пусть аксиоматическая теория непротиворечива. Тогда в ней существует утверждение, которое нельзя ни доказать, ни опровергнуть. Вторая теорема о неполноте. Непротиворечивость теории не может быть доказана методами, которые в ней формализуются. 17 ТЕОРЕМА О ЧЕТЫРЕХ КРАСКАХ Теорема о четырех красках на протяжении почти 100 лет оставалась одной из самых известных нерешенных задач математики. В 1976 году американские математики Кеннет Аппель и Вольфганг Хакен решили проблему с помощью компьютера. Доказательство состояло из двух шагов: 1. Все возможные варианты карт сводились к большому (но тем не менее проверяемому на компьютере) числу карт. 2. Осуществлялась компьютерная проверка отобранных вариантов. 18 ГИПОТЕЗА РИМАНА Формулировка гипотезы: все нетривиальные нули дзета-функции лежат на прямой 𝑅𝑒 𝑠 = 1/2. Вычислены первые 1013 нулей дзета-функции плюс по несколько миллиардов нулей на очень большой высоте. Все они лежат на критической прямой. 19 4. ВЫЧИСЛИМЫЕ ПО ТЬЮРИНГУ ФУНКЦИИ Машина Тьюринга включает в себя: 1. Бесконечную в обе стороны ленту, разбитую на клетки. 2. Читающую и пишущую головку. 3. Внешний алфавит 𝐴 = 𝑎0 , 𝑎1 , … , 𝑎𝑟 . Среди букв алфавита 𝐴 есть один пустой символ 𝑎0 = ∅. 4. Множество внутренних состояний 𝑄 = {𝑞0 , 𝑞1 , … , 𝑞𝑛 } для читающей и пишущей головки. Состояние 𝑞0 означает завершение работы. 21 𝒒𝒊 Работа машины полностью определяется указанием ее конфигурации в начальный момент времени: 1. Распределение букв на ленте (обычно рассматривают конфигурации, в которых лишь конечное число непустых символов). 2. Клетка, обозреваемая головкой. 3. Состояние головки. За один такт работы головка может изменить содержимое обозреваемой ячейки и внутренне состояние и переместиться к одной из соседних ячеек (или остаться на месте). Таким образом, работа машины описывается тремя функциями: 𝛼: 𝑄 × 𝐴 → 𝑄 новое состояние 𝛽: 𝑄 × A → 𝐴 новое содержимое ячейки 𝛾: 𝑄 × 𝐴 → {𝑁, 𝐿, 𝑅} движение головки 𝑁 − 𝐿 − 𝑅 остаться на месте – на одну позицию влево – на одну позицию вправо Обозначение: 𝑞𝑎 ↦ 𝛼 𝑞, 𝑎 𝛽 𝑞, 𝑎 𝛾(𝑞, 𝑎) 22 СЛОЖЕНИЕ НАТУРАЛЬНЫХ ЧИСЕЛ Используем унарную запись натуральных чисел: 𝑛 ⟷ 11 … 1 (𝑛 раз). ∅ 1 1 1 + 1 1 ∅ 1 1 1 1 1 ∅ Сложим 3 + 2. 𝑞1 ∅ ↦ 𝑞1 ∅𝑅 𝑞1 1 ↦ 𝑞1 1𝑅 𝑞1 +↦ 𝑞2 1𝑅 𝑞2 1 ↦ 𝑞2 1𝑅 𝑞2 ∅ ↦ 𝑞3 ∅𝐿 𝑞3 1 ↦ 𝑞0 ∅𝐿 23 ВЫЧИСЛИМЫЕ ПО ТЬЮРИНГУ ФУНКЦИИ Определение. Функция 𝑓 называется вычислимой по Тьюрингу, если существует машина Тьюринга, позволяющая вычислять ее значения для всех наборов из области определения функции и работающая бесконечно долго для тех наборов, для которых функция не определена. Тезис Тьюринга. Некоторый алгоритм для нахождения значений функции, заданной в некотором алфавите, существует тогда и только тогда, когда функция является вычислимой по Тьюрингу. Тезис эмпирический (в принципе не доказуем) и постулирует равнозначность понятий алгоритмической вычислимости и вычислимости по Тьюрингу. 24 5. РЕКУРСИВНЫЕ ФУНКЦИИ Базовые функции: 𝑆 𝑥 =𝑥+1 𝑂 𝑥 =0 𝑛 𝐼𝑚 𝑥1 , … , 𝑥𝑛 = 𝑥𝑚 (функция следования). (нуль-функция). (функции-проекторы, 1 ≤ 𝑚 ≤ 𝑛). Оператор суперпозиции 𝑇: 𝑇 𝑓; 𝑔1 , … , 𝑔𝑚 = 𝑓 𝑔1 , … , 𝑔𝑚 , где 𝑓 - 𝑚-местная функция, 𝑔1 , … , 𝑔𝑚 - 𝑛-местные функции. В результате получается 𝑛-местная функция. Оператор примитивной рекурсии 𝑅: 𝜑 = 𝑅 𝑓, 𝑔 , где 𝑓- 𝑛-местная, 𝑔 - (𝑛 + 2)-местная, 𝜑- (𝑛 + 1)-местная. По определению для любых 𝑥1 , … , 𝑥𝑛 , 𝑦 справедливы равенства: 𝜑 𝑥1 , … , 𝑥𝑛 , 0 = 𝑓 𝑥1 , … , 𝑥𝑛 𝜑 𝑥1 , … , 𝑥𝑛 , 𝑦 + 1 = 𝑔(𝑥1 , … , 𝑥𝑛 , 𝑦, 𝜑 𝑥1 , … , 𝑥𝑛 , 𝑦 ) 26 В определении оператора примитивной рекурсии 𝑦 понимается как счетчик итераций, 𝑓- как исходная функция в начале итерационного процесса, и 𝑔 - как оператор, принимающий на вход 𝑛 переменных, номер шага итерации, функцию на данном шаге итерации, и возвращающий функцию на следующем шаге итерации. Примитивно-рекурсивные функции: минимальное множество, содержащее все базовые функции и замкнутое относительно операторов суперпозиции и примитивной рекурсии. 27 Оператор минимизации: Пусть 𝑓 – функция от 𝑛 натуральных переменных. Тогда результатом применения оператора минимизации к функции 𝑓 является функция ℎ от 𝑛 − 1 переменной, задаваемая следующим условием: ℎ 𝑥1 , … , 𝑥𝑛−1 = min 𝑦, при условии 𝑓 𝑥1 , … , 𝑥𝑛−1 , 𝑦 = 0. То есть функция ℎ возвращает минимальное значение последнего аргумента функции 𝑓, при котором ее значение равно 0. Частично-рекурсивные функции: определяются аналогично примитивно рекурсивным, только к двум операторам суперпозиции и примитивной рекурсии добавляется еще третий оператор — минимизации аргумента. 28 Частично рекурсивные функции для некоторых значений аргумента могут быть не определены, так как оператор минимизации аргумента не всегда корректно определен, поскольку функция может быть не равной нулю ни при каких значениях аргументов. С точки зрения программирования, результатом частично рекурсивной функции может быть не только число, но и исключение или уход в бесконечный цикл, соответствующие неопределенному значению. Общерекурсивная функция — частично рекурсивная функция, определенная для всех значений аргументов. Задача определения того, является ли частично рекурсивная функция с данным описанием общерекурсивной или нет, алгоритмически неразрешима. 29 6. АНАЛИЗ АЛГОРИТМОВ Временная сложность алгоритма – время, затрачиваемое алгоритмом для получения результата. Пространственная сложность алгоритма – объем памяти, используемой алгоритмом, для получения результата. Временную сложность оценивают как характер функциональной зависимости числа элементарных операций, выполняемых алгоритмом для решения задачи, от размера входных данных. Обозначим временную функцию сложности алгоритма через 𝑇(𝑛), где 𝑛 – размер входных данных. 31 Алгоритм называется полиномиальным, если его временная функция сложности имеет полиномиальный рост по 𝑛. Класс 𝑷 состоит из множества задач, для которых существует решающий их алгоритм полиномиальной сложности. PSPACE – набор задач, которые могут быть вычислены на некоторой машине Тьюринга 𝑀, для которой необходимая для вычислений память (наиболее удаленное от начала головки место на ленте в процессе вычислений) 𝑆𝑀 𝑛 = 𝑝𝑜𝑙𝑦(𝑛). Класс 𝑵𝑷 недетерминированных схем полиномиального размера: состоит из задач, для которых существует схема полиномиального по 𝑛 размера, проверяющая предложенное решение за полиномиальное время. Очевидно, что 𝑃 ⊂ 𝑁𝑃. Открытая задача: совпадают ли классы 𝑃 и 𝑁𝑃? 𝑁𝑃-полная задача: задача из класса 𝑁𝑃, к которой можно свести любую другую задачу из этого класса за полиномиальное время. 32 7. КЛАССИЧЕСКИЕ ВЫЧИСЛИТЕЛЬНЫЕ СХЕМЫ Классический компьютер: на входе - 𝑛 бит, на выходе - 𝑚 бит. То есть 𝑓 ∶ 0,1 𝑀 = 0,1 𝑚, 𝑁 𝑛 → 0,1 𝑚 = 0,1 𝑛 . Число таких функций - #𝑀#𝑁 . Любую такую функцию можно выразить через функции с однобитовыми значениями 𝑓 ∶ 0,1 34 𝑛 → 0,1 (1) Теорема. Любая булева функция может быть вычислена с помощью трех логических операций: AND, OR, NOT. Замечание. То, что для вычисления любой функции, зависящей от конечного входа, достаточно лишь нескольких элементарных операций, является фундаментальным результатом классической теории вычислений. Он означает, что с помощью очень простых аппаратных средств можно выполнить сколь угодно сложные вычисления. 35 Доказательство. Для заданной функции 𝑓 рассмотрим два множества входных значений: 𝑋0 = 𝑓 −1 0 , 𝑋1 = 𝑓 −1 {1} Перенумеруем все элементы множества 𝑋1 = {𝑎1 , 𝑎2 , … , 𝑎𝑚 } и для каждого 𝑎𝑖 определим функцию 𝑓𝑖 ∶ 0,1 36 𝑛 → 0,1 по формуле: 𝑓𝑖 𝑥 = 1, 0, 𝑥 = 𝑎𝑖 𝑥 ≠ 𝑎𝑖 Тогда 𝑓 𝑥 = 𝑓1 𝑥 ∨ 𝑓2 𝑥 ∨ ⋯ ∨ 𝑓𝑚 𝑥 (дизъюнктивная нормальная форма 𝑓(𝑥)). Легко видеть, что вычисление функций 𝑓𝑖 (𝑥) можно осуществить с помощью еще двух логических операций AND и NOT. 37 В развернутом виде д.н.ф. можно записать следующим образом: 𝑥1 𝜎1 & … &𝑥𝑛 𝜎𝑛 𝑓 𝑥1 , … , 𝑥𝑛 = 𝜎1 ,…,𝜎𝑛 : 𝑓 𝜎1 ,…,𝜎𝑛 =1 где 𝑥 𝜎 = 𝑥, если 𝜎 = 1 𝑥 , если 𝜎 = 0 Теорема доказана. 38 Пример 1. Из четырех 1 → 1 вентилей обратимы два: тождественный и NOT. Пример 2. Из 44 = 256 вентилей 2 → 2 обратимых 4! (проверьте). Один из самых важных вентилей в этом ряду: 𝑋𝑂𝑅 ∶ 𝑥, 𝑦 ↦ (𝑥, 𝑥⨁𝑦) Очевидно, что 𝑋𝑂𝑅−1 = 𝑋𝑂𝑅. 39 Теорема (без доказательства). Универсальным вентилем для обратимых вычислений является вентиль Тоффоли 𝜃 3 : 𝑥, 𝑦, 𝑧 ↦ (𝑥, 𝑦, 𝑧 ⊕ 𝑥 ⋅ 𝑦) то есть, используя только его, можно построить схему, вычисляющую любую обратимую функцию 𝑓 ∶ 0,1 40 𝑛 → 0,1 𝑛 8. СОРТИРОВКА И ПОИСК СОРТИРОВКА ВСТАВКАМИ На первом шаге берем первый слева элемент массива. Пусть первые (слева) 𝑛 − 1 элемента массива уже упорядочены. Берем 𝑛-ый элемент и ставим его на нужное место упорядоченной части массива, двигаясь справа налево. 42 9 3 7 1 8 𝑗=1 3 9 7 1 8 𝑗=2 3 7 9 1 8 𝑗=3 1 3 7 9 8 𝑗=4 1 3 7 8 9 АНАЛИЗ СЛОЖНОСТИ 𝑇 𝑛 = 𝑛𝑗=2 𝑡𝑗 , где 𝑡𝑗 - это количество перестановок элементов на 𝑗-ом шаге. Таким образом, сложность зависит от того, насколько упорядочен был исходный вектор. Самый благоприятный случай: вектор упорядочен, 𝑡𝑗 = 1 для всех 𝑗 и 𝑇 𝑛 ≃ 𝑛. Среднее время работы алгоритма: 𝑡𝑗 = 𝑗/2 для всех 𝑗, 𝑇 𝑛 ≃ 𝑛2 /4 Наихудший случай: 𝑡𝑗 = 𝑗 для всех 𝑗, 𝑇 𝑛 ≃ 𝑛2 /2 Таким образом, алгоритм квадратичный. 43 СОРТИРОВКА ВЫБОРОМ Берем первый элемент массива 𝑎[1] и последовательно сравниваем его с элементами 𝑎 2 , 𝑎[3] и т.д. до тех пор, пока не встретится элемент меньший, чем 𝑎 1 . Тогда меняем этот меньший элемент с элементом 𝑎[1] местами и продолжаем по тому же принципу сравнивать последующие элементы массива с уже новым элементом 𝑎[1], пока не дойдем до конца массива – элемента 𝑎 𝑛 . После этого переходим к элементу 𝑎[2] и т.д. Сложность алгоритма, очевидно, квадратичная: 𝑇 𝑛 ∼ 𝑛2 44 СОРТИРОВКА СЛИЯНИЕМ 𝑛 Исходный массив разбиваем на два массива индексом 2 и к каждой части применяем рекурсивный алгоритм. Отсортированные части сливаем в один отсортированный массив следующим образом: части отсортированы по возрастанию, поэтому наименьший элемент исходного массива – это первый элемент одной из двух частей. Сравниваем первые элементы и записываем наименьший из них в качестве первого элемента большого массива. Дальше снова сравниваем первые элементы двух частей (длина одной из них уменьшилась на единицу) и наименьший из них будет вторым элементом большого массива. И т.д. В результате на слияние потребуется 𝑂(𝑛) операций. Сложность: 𝑇 𝑛 = 𝑂(𝑛 log 𝑛) 45 РАНДОМИМЗИРОВАНННАЯ СОРТИРОВКА Алгоритм рекурсивный. Из массива размера 𝑛 выбирается произвольный элемент 𝑎 𝑖0 . Оставшиеся (𝑛 − 1) элементов массива делятся на две части: элементы, которые меньше 𝑎[𝑖0 ] и элементы, которые больше 𝑎 𝑖0 . Каждую из частей упорядочиваем, применяя к ней этот же алгоритм по рекурсивному принципу. Элемент 𝑎[𝑖0 ] при этом остается на месте. 46 ДВОИЧНЫЙ ПОИСК Алгоритм рекурсивный. Ищем число 𝑘 в отсортированном массиве 𝑎[1. . 𝑛]. Сравниваем число 𝑘 со средним значением 𝑎 𝑛 2 . Далее применяем алгоритм поиска рекурсивно к первой половине массива 𝑎 1. . 𝑛 , если 𝑘 < 𝑎 второй половине массива, если 𝑘 > 𝑎 𝑛 2 𝑛 2 , или ко . В обозначениях теоремы о рекурсивных алгоритмах 𝑎 = 1, 𝑏 = 2, 𝑑 = 0. Поэтому 𝑇 𝑛 = 𝑂(log 𝑛), что является значительным улучшением по сравнению с ожидаемыми 𝑛/2 сравнениями при последовательном поиске. 47 9. РЕКУРСИВНЫЕ АЛГОРИТМЫ Замечание. Рассмотрим геометрическую прогрессию 𝑓 𝑛 = 1 + 𝑞 + ⋯ + 𝑞𝑛 где 𝑞 > 0. Тогда 1. 𝑓 𝑛 = 𝑂(1) при 𝑞 < 1. 2. 𝑓 𝑛 = 𝑂(𝑛) при 𝑞 = 1. 3. 𝑓 𝑛 = 𝑂(𝑞 𝑛 ) при 𝑞 > 1. 49 Пусть рекурсивный алгоритм сводит исходную задачу размера 𝑛 к 𝑎 подзадачам размера 𝑛/𝑏 и из найденных решений строит ответ для исходной задачи. Будем считать, что на разбиение и сборку уходит время 𝑂 𝑛𝑑 . Таким образом, рекуррентное соотношение на время работы такого алгоритма: 𝑇 𝑛 = 𝑎𝑇 𝑛 𝑏 + 𝑂 𝑛𝑑 Теорема. Пусть 𝑇(𝑛) удовлетворяет вышеприведенному рекуррентному уравнению для некоторых 𝑎 > 0, 𝑏 > 1, 𝑑 ≥ 0. Тогда 𝑂 𝑛𝑑 , если 𝑑 > log 𝑏 𝑎 𝑇 𝑛 = 𝑂 𝑛𝑑 log 𝑛 , если 𝑑 = log 𝑏 𝑎 𝑂 𝑛log𝑏 𝑎 , если 𝑑 < log 𝑏 𝑎 50 Доказательство. Можно считать, что 𝑛 есть степень 𝑏 (нас интересует только асимптотика). Дерево работы алгоритма имеет log 𝑏 𝑛 уровней. Коэффициент ветвления алгоритма есть 𝑎, так что 𝑘-й уровень содержит 𝑎𝑘 подзадач размера 𝑛/𝑏𝑘 . Размер подзадачи 𝑛 Размер подзадачи 𝑛/𝑏 Размер подзадачи 𝑛/𝑏2 51 Количество операций, которое алгоритм производит на этом уровне, есть 𝑘 𝑡𝑘 = 𝑎 𝑂 𝑛 𝑏𝑘 𝑑 =𝑂 𝑛 𝑑 𝑎 𝑏𝑑 𝑘 Последовательность {𝑡𝑘 } где 𝑘 меняется от 0 до log 𝑏 𝑛 есть геометрическая 𝑎 прогрессия со знаменателем 𝑏𝑑 . Надо воспользоваться замечанием про геометрическую прогрессию. Теорема доказана. 52 Алгоритм Штрассена. Сначала вычисляем матрицы: 𝑃1 = 𝐴11 𝐵12 − 𝐵22 , 𝑃2 = 𝐴11 + 𝐴12 𝐵22 , 𝑃3 = 𝐴21 + 𝐴22 𝐵11 , 𝑃4 = 𝐴22 𝐵21 − 𝐵11 , 𝑃5 = 𝐴11 + 𝐴22 𝐵11 + 𝐵22 , 𝑃6 = 𝐴12 − 𝐴22 𝐵21 + 𝐵22 , 𝑃7 = 𝐴11 − 𝐴21 𝐵11 + 𝐵12 . 53 Затем вычисляем произведение: 𝐴𝐵 = Время работы: 𝑇 𝑛 = 7𝑇 𝑃5 + 𝑃4 − 𝑃2 + 𝑃6 𝑃3 + 𝑃4 𝑛 2 + 𝑂 𝑛2 . Следовательно, 𝑇 𝑛 = 𝑂 𝑛log2 7 ≃ 𝑂(𝑛2,81 ) 54 𝑃1 + 𝑃2 𝑃1 + 𝑃5 − 𝑃3 − 𝑃7 10. ЭЛЕМЕНТАРНЫЕ ОПЕРАЦИИ СЛОЖЕНИЕ 1 1 1 0 1 0 1 53 1 0 0 0 1 1 35 0 1 1 0 0 0 88 Сложность: 𝑂 𝑛 , где 𝑛 – максимум числа битов в записи входящих чисел. Если число обозначить через 𝑁, то 𝑛 ≃ log 2 𝑁. Таким образом, 𝑇 𝑁 = ln 𝑁. Ясно, что существенно более быстрого алгоритма не существует. В смысле порядка сложности этот алгоритм оптимален. 56 ВЫЧИТАНИЕ 1 1 1 0 0 1 0 0 1 105 1 0 0 1 1 19 1 0 1 1 0 86 Сложность: T n = 𝑂 𝑛 . 57 УМНОЖЕНИЕ СТОЛБИКОМ 1 1 1 1 0 0 1 1 1 0 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 0 1 1 1 1 Сложность: T n = 𝑂 𝑛2 или 𝑇 𝑁 = 𝑂(ln2 𝑁) = 𝑂(ln 𝑁) Упражнение. Доказать корректность этого алгоритма. 58 РЕКУРСИВНОЕ УМНОЖЕНИЕ Рассмотрим два 𝑛-битовых числа 𝑥 и 𝑦 и без ограничения общности будем считать, что 𝑛 есть степень двойки (если это не так, допишем слева недостающие нули). Разобьем каждое из чисел 𝑥 и 𝑦 пополам: 𝑥= 𝒙𝑳 𝒙𝑹 = 2𝑛/2 𝑥𝐿 + 𝑥𝑅 𝑦= 𝒚𝑳 𝒚𝑹 = 2𝑛/2 𝑦𝐿 + 𝑦𝑅 𝑥𝑦 = 59 𝑛 22 𝑥𝐿 + 𝑥𝑅 𝑛 22 𝑦𝐿 + 𝑦𝑅 = 2𝑛 𝑥𝐿 𝑦𝐿 + 𝑛 22 𝑥𝐿 𝑦𝑅 + 𝑥𝑅 𝑦𝐿 + 𝑥𝑅 𝑦𝑅 РЕКУРСИВНОЕ УМНОЖЕНИЕ Гаусс заметил, что для вычисления произведения комплексных чисел 𝑎 + 𝑏𝑖 𝑐 + 𝑑𝑖 = 𝑎𝑐 − 𝑏𝑑 + 𝑏𝑐 + 𝑎𝑑 𝑖 достаточно вычислить три произведения 𝑎𝑐, 𝑏𝑑, (𝑎 + 𝑏)(𝑐 + 𝑑) и воспользоваться тождеством: 𝑏𝑐 + 𝑎𝑑 = 𝑎 + 𝑏 𝑐 + 𝑑 − 𝑎𝑐 − 𝑏𝑑 Применим это наблюдение для вычисления произведения 𝑥𝑦. То есть будем вычислять три произведения: 𝑥𝐿 𝑦𝐿 , 𝑥𝑅 𝑦𝑅 , 𝑥𝐿 + 𝑥𝑅 𝑦𝐿 + 𝑦𝑅 . Тогда 𝑥𝐿 𝑦𝑅 + 𝑥𝑅 𝑦𝐿 = 𝑥𝐿 + 𝑦𝐿 𝑦𝐿 + 𝑦𝑅 − 𝑥𝐿 𝑥𝑅 − 𝑦𝐿 𝑦𝑅 60 РЕКУРСИВНОЕ УМНОЖЕНИЕ Таким образом, 𝑎 = 3, 𝑏 = 2 (перемножаем три числа вдвое меньшего размера), причем в формуле для вычисления 𝑥𝑦 сложение и умножение на степень двойки (сдвиг влево) производятся за линейное по 𝑛 время (то есть 𝑑 = 1). Следовательно, по основной теореме о рекурсивных алгоритмах: 𝑇 𝑛 = 𝑂 𝑛log2 3 ≤ 𝑂(𝑛1,59 ) Существует и более быстрый способ умножения, основанный на быстром преобразовании Фурье. 61 ДЕЛЕНИЕ 10101001 (делимое) -1001 001 11 110 1100 -1001 111 (остаток) 1001 (делитель) 10010 (частное) (положит. остаток, 1 в частное) (отрицат. остаток, 0 в частное) (отрицат. остаток, 0 в частное) (положит. остаток, 1 в частное) (отрицат. остаток, 0 в частное) Сложность: 𝑂 n ⋅ m , где 𝑛 – длина делимого, 𝑚 - длина делителя. 62 11. БПФ УМНОЖЕНИЕ МНОГОЧЛЕНОВ 𝑃 𝑥 = 𝑛 𝑖 𝑖=0 𝑎𝑖 𝑥 , 𝑄 𝑥 = 𝑛 𝑗 𝑗=0 𝑏𝑗 𝑥 2𝑛 𝑐𝑘 𝑥 𝑘 𝑃 𝑥 𝑄 𝑥 = 𝑘=0 где 𝑐𝑘 = 𝑖+𝑗=𝑘 𝑎𝑖 𝑏𝑗 . Сложность. 𝑇 𝑛 = 𝑂 𝑛2 . Для чего нужно уметь быстро умножать многочлены? 64 АЛГОРИТМ УМНОЖЕНИЯ МНОГОЧЛЕНОВ Вход: коэффициенты многочленов 𝑃 𝑥 , 𝑄(𝑥) степени не выше 𝑛. Выход: коэффициенты многочлена 𝑆 𝑥 = 𝑃 𝑥 ⋅ 𝑄 𝑥 . Выбор: выбираем точки 𝑥0 , … , 𝑥𝑁−1 в количестве 𝑁 ≥ 2𝑛 + 1. Вычисление: вычисляем 𝑃 𝑥0 , … , 𝑃(𝑥𝑁−1 ) и 𝑄 𝑥0 , … , 𝑄 𝑥𝑁−1 . Умножение: вычисляем 𝑆 𝑥𝑘 = 𝑃 𝑥𝑘 ⋅ 𝑄(𝑥𝑘 ) для всех 𝑘 = 0, … , 𝑁 − 1. Интерполяция: восстанавливаем коэффициенты многочлена 𝑆(𝑥) по значениям в точках 𝑥0 , … , 𝑥𝑁−1 . 65 РЕКУРСИВНОЕ ВЫЧИСЛЕНИЕ ЗНАЧЕНИЙ МНОГОЧЛЕНА Если вычислять значения многочленов в точках по определению, то сложность такого алгоритма будет 𝑛2 . Мы хотим произвести вычисления за время 𝑛 log 𝑛. Представим многочлен 𝑃(𝑥) в виде суммы 𝑃 𝑥 = 𝑃0 𝑥 2 + 𝑥𝑃1 (𝑥 2 ), где коэффициенты многочленов 𝑃0 (𝑥) и 𝑃1 𝑥 соответствуют коэффициентам многочлена 𝑃(𝑥), соответственно, при четных и при нечетных степенях аргумента. Далее выбираем 𝑁 точек, разбитых на пары, отличающиеся знаком: ±𝑥0 , ±𝑥1 , … , ±𝑥𝑁 2 −1 66 РЕКУРСИВНОЕ ВЫЧИСЛЕНИЕ ЗНАЧЕНИЙ МНОГОЧЛЕНА Функции 𝑃0 (𝑥) и 𝑃1 (𝑥) – четные. Поэтому вычисление значений 𝑃(𝑥) в 𝑁 точках 𝑁 ± 𝑥𝑖 , 𝑖 = 0, … , 2 − 1 сводится к вычислению значений двух многочленов 𝑃0 (𝑥) и 𝑁 𝑃1 (𝑥) вдвое меньшей степени в 2 точках 𝑥0 , … , 𝑥𝑁 . 2 67 РЕКУРСИВНОЕ ВЫЧИСЛЕНИЕ ЗНАЧЕНИЙ МНОГОЧЛЕНА Осталось решить следующую задачу: на каждом шаге рекурсии точки, в которых вычисляется значение многочлена, должны быть разбиты на пары, которые отличаются только знаком. Будем считать, что 𝑁 – это степень двойки (при этом количество точек увеличится не более чем в два раза). В качестве точек 𝑥𝑘 берем корни 𝑁-ой степени из единицы, то есть 𝑥0 , … , 𝑥𝑁−1 = 𝑈𝑁 . Тогда квадраты этих точек – это 𝑁 корни степени 2 (натуральное число, поскольку 𝑁 – это степень двойки) из единицы и т.д. 68 СЛОЖНОСТЬ АЛГОРИТМА На каждом шаге рекурсии задача сводится к двум подзадачам вдвое меньшего размера, после чего за линейное время можно найти ответ. Таким образом, 𝑎 = 2, 𝑏 = 2, 𝑑 = 1. По основной теореме о рекурсии 𝑇 𝑛 = 𝑂(𝑛 log 𝑛) . 69 ИНТЕРПОЛЯЦИЯ ПРИ ПОМОЩИ БПФ Если точки {𝑥𝑘 } являются корнями 𝑁-ой степени из единицы, то при помощи быстрого преобразования Фурье (FFT – fast Fourier transform) за время 𝑂(𝑛 log 𝑛) можно перейти от коэффициентов многочлена к значениям многочлена в этих точках. <значения> = FFT(<коэффициенты>, {𝑥𝑘 }). Оказывается, что обратная задача (интерполяции) решается за то же время с помощью FFT (используется обратное преобразование Фурье): 1 <коэффициенты> = 𝑛 FFT(<значения>,{𝑥𝑘 −1 }). 70 ЛАБОРАТОРИЯ КАСПЕРСКОГО Kaspersky Lab HQ 39A/3 Leningradskoe Shosse Moscow, 125212, Russian Federation Tel: +7 (495) 797-8700 www.kaspersky.com