
- •Предисловие
- •Введение
- •Алгоритмы и их сложность
- •Примеры задач и алгоритмов
- •Задачи на графах: «Коммивояжер», «Кратчайшие пути», «Остовные деревья»
- •Приближенные алгоритмы: «Составление расписаний»
- •«Сортировка слиянием»
- •«Быстрая сортировка»
- •Формально об алгоритмах. Несложно о сложности
- •«RAM»: машины с произвольным доступом
- •Сложность в худшем случае
- •Сложность в среднем
- •Полиномиальные алгоритмы
- •Полиномиальность и эффективность
- •Аппроксимация с гарантированной точностью
- •Алгоритмы с оценками точности
- •Жадные алгоритмы для «Покрытия множеств»
- •Приближенные алгоритмы для «Вершинного покрытия»
- •Жадный алгоритм для «Рюкзака»
- •Алгоритм Кристофидеса
- •Аппроксимация с заданной точностью
- •«Рюкзак»: динамическое программирование
- •Полностью полиномиальная приближенная схема для «Рюкзака»
- •Вероятностный анализ детерминированных алгоритмов
- •Сложность и полиномиальность в среднем
- •Задача упаковки
- •Выполнимость КНФ
- •Точность алгоритма для почти всех входов
- •«Рюкзак»: полиномиальность в среднем
- •Вероятностные алгоритмы и их анализ
- •Вероятностная проверка тождеств
- •Максимальное по включению независимое множество в графе
- •Протокол византийского соглашения
- •Вероятностное округление
- •Максимальный разрез в графе
- •Методы дерандомизации
- •Метод условных вероятностей
- •Метод малых вероятностных пространств
- •Полиномиальная проверка простоты
- •Основы теории сложности вычислений
- •Сложность вычислений
- •Машины Тьюринга и вычислимость
- •Сводимость по Куку
- •Недетерминированные алгоритмы
- •Сводимость по Карпу
- •Вероятностные вычисления
- •Вероятностно проверяемые доказательства
- •Схемы и схемная сложность
- •Коммуникационная сложность
- •Диаграмма классов сложности
- •Приложения
- •Введение в Python
- •Глоссарий
- •Предметный указатель
- •Список алгоритмов
1.2. ФОРМАЛЬНО ОБ АЛГОРИТМАХ. НЕСЛОЖНО О СЛОЖНОСТИ |
67 |
Таким образом, сильно полиномиальные алгоритмы обобщают однородные полиномиальные алгоритмы. Хорошим примером сильно полиномиального алгоритма, который, по-видимому, нельзя привести к однородному виду (т. е. избавиться от делений и умножений), служит известный алгоритм Гаусса решения систем линейных уравнений.
Итак, отличительной чертой сильно полиномиальных алгоритмов является то, что время их работы ограничено полиномом от размерности задачи. На другом полюсе находятся псевдополиномиальные алгоритмы, в которых требуется, чтобы время работы алгоритма было полиномиально лишь от суммы абсолютных значений (а не от битовой длины записи) входящих в задачу числовых параметров. Типичные примеры таких алгоритмов приведены в разделе 2.2.1.
1.2.5Полиномиальность и эффективность
Может ли полиномиальный алгоритм быть неэффективным? Разумеется, может, если в полиномиальной оценке времени его работы t(n) C nk либо мультипликативная константа C, либо показатель k чрезмерно велики.
Опыт показывает, что такое случается крайне редко, и подавляющее большинство полиномиальных алгоритмов для естественных задач удовлетворяет оценке t(n) 10 n3. В тех же немногих случаях, когда полиномиальный алгоритм оказывается малопригодным с практической точки зрения, это обстоятельство всегда стимулирует бурные исследования по построению на его основе действительно эффективного алгоритма, что, как правило, приводит к интересным самим по себе побочным следствиям. Хрестоматийным примером такого рода может служить метод эллипсоидов для линейного программирования [Kha79], стимулировавший бурное развитие целого направления ([Kar84]), получившего название «метод внутренней точки» и занявшего в настоящее время лидирующие позиции в разработке наиболее эффективных алгоритмов для задач линейного программирования большой размерности.
68 |
Глава 1. АЛГОРИТМЫ И ИХ СЛОЖНОСТЬ |
Кстати, одна из самых известных современных открытых проблем в теории алгоритмов (и вообще математики) заключается в ответе на вопрос: «существует ли сильно полиномиальный алгоритм для задачи линейного программирования?» ([Sma00]).
Упражнение 1.2.1. Посмотрите на каждый из приведенных ранее алгоритмов и определите, является ли он полиномиальным, сильно полиномиальным или псевдополиномиальным?
Может ли неполиномиальный алгоритм быть эффективным? Ответ утвердительный, по меньшей мере, по трем причинам. Во-первых, может случиться так, что примеры, на которых время работы алгоритма велико, настолько редки, что вероятность обнаружить хотя бы один из них на практике пренебрежимо мала. В математических терминах это означает, что алгоритм полиномиален в среднем относительно любого «разумного» вероятностного распределения и, по-видимому, под эту категорию попадает симплексметод (см. [Схр91]).
Во-вторых, многие псевдополиномиальные алгоритмы являются эффективными, когда возникающие на практике числовые параметры не слишком велики.
Наконец, субэкспоненциальные алгоритмы, время работы которых, например, имеет вид O(nc log log log n), при всех разумных длинах входа n могут быть весьма практически эффективными.
Но в заключение еще раз подчеркнем, что примеров задач, на которых нарушается основополагающее равенство
«полиномиальность»=«эффективность»
крайне мало по сравнению с числом примеров, на которых оно блестяще подтверждается.
Отметим, что единственную серьезную конкуренцию машинам RAM как основы для построения теории сложности вычислений на сегодняшний день составляют так называемые машины Тьюринга, которые мы будем рассматривать в разделе 6.1. Их принципиальное отличие состоит в отсутствии непрямой
1.2. ФОРМАЛЬНО ОБ АЛГОРИТМАХ. НЕСЛОЖНО О СЛОЖНОСТИ |
69 |
индексации: после проведения каких-либо действий с некоторой ячейкой процессор («головка») может перейти лишь в одну из «соседних» ячеек. Машины Тьюринга удобны при рассмотрении комбинаторных задач с небольшим количеством числовых параметров, а также (в силу своей структурной простоты) для теоретических исследований.