- •Содержание
- •1 Элементы теории множеств. Комбинаторика. 5
- •Математическая логика: Булева аллгебра 88
- •Теория алгоритмов 129
- •Теория графов 162
- •Математическая логика: Исчисления высказываний и предикатов 207
- •Элементы теории множеств. Комбинаторика.
- •Введение
- •Примеры задач.
- •Задача о расположении конвертов
- •Задача о Ханойской башне
- •Базовые обозначения
- •Правило суммы и правило произведения
- •Основы теории множеств
- •Понятие множества
- •Парадокс Рассела
- •Подмножества
- •Операции над множествами
- •Диаграммы Эйлера-Венна
- •Прямое произведение множеств
- •Бинарные отношения и функции
- •Бинарные отношения
- •Функции
- •Специальные бинарные отношения: Отношение эквивалентности
- •Специальные бинарные отношения: Отношение порядка
- •Лексикографический порядок
- •Выборки с повторениями и без повторений
- •Размещения и сочетания
- •Треугольник Паскаля
- •Связь сочетаний и (0,1)-векторов
- •Перебор сочетаний
- •Бином Ньютона
- •Мультимножества
- •Связь мультимножеств и (0,1)-векторов
- •Полином Ньютона
- •Разбиения множеств.
- •Приложение: программа перебора сочетаний
- •Перестановки
- •Понятие перестановки
- •Группа перестановок
- •Циклы перестановки
- •Тип перестановки
- •Разложения и разбиения натуральных чисел
- •Разложения натуральных чисел
- •Разбиения натуральных чисел
- •Принцип включения-исключения
- •Принцип включения-исключения
- •Задача о беспорядках
- •Мощность объединения множеств
- •Число целочисленных решений системы неравенств
- •Математическая логика: Булева аллгебра
- •Булева алгебра. Функции алгебры логики.
- •Булевы функции
- •Формулы
- •Основные тождества
- •Разложение функции по переменным
- •Дизъюнктивная и конъюнктивная нормальные формы
- •Полином Жегалкина
- •1 ⊕ X1 ⊕ x2x3 - полином Жегалкина.
- •Полнота системы функций
- •Функции, сохраняющие ноль
- •Функции, сохраняющие единицу
- •Двойственность
- •Монотонность
- •Линейность
- •Критерий полноты системы функций
- •Теория алгоритмов
- •Машины Тьюринга
- •Понятие алгоритма
- •Машина Тьюринга
- •Способы записи машины Тьюринга
- •Стандартные конфигурации
- •Вычислимые функции
- •Алгоритмически неразрешимые задачи
- •Сложность алгоритма
- •Полиномиальная сводимость
- •Классы задач в форме распознавания свойств
- •4 Теория графов
- •4.1 Определения графа
- •Общее определение
- •Виды графов
- •Обыкновенный граф
- •Примеры графов
- •Графы Бержа
- •4.2 Изоморфизм графов
- •4.2.1 Инварианты графа
- •Операции
- •Основные операции над графами
- •Подграфы
- •Дополнение графа
- •Маршруты и связность
- •Деревья
- •Матрицы, связанные с графом
- •Матрица смежности
- •Матрица инцидентности
- •Список ребер
- •Обходы графов
- •Эйлеров цикл
- •Гамильтонов цикл
- •Задачи и алгоритмы
- •Остов минимального веса
- •Алгоритм 4.8.1 (Алгоритм Краскала).
- •Задача коммивояжера
- •Задача о клике
- •Задача о вершинном покрытии
- •Задача о гамильтоновом цикле
- •Снова задача коммивояжера
- •Алгоритм дерева
- •Математическая логика: Исчисления высказываний и предикатов
- •Исчисление высказываний
- •Пример задачи логики высказываний
- •Формальные теории
- •Формальная теория исчисление высказываний
- •Теоремы исчисления высказываний
- •Теорема о полноте исчисления высказываний
- •Независимость аксиом исчисления высказываний
- •Исчисление предикатов
- •Пример задачи логики предикатов
- •Формальная теория исчисление предикатов
- •Алфавит.
- •Формулы.
- •Аксиомы.
- •Правила вывода.
- •Интерпретация
- •Литература
Сложность алгоритма
Когда идет речь о сложности алгоритма, обычно имеется в виду скорость выполнения алгоритма (временная сложность) или требуемая для его работы память (емкостная сложность). При оценке времени выполнеия, память чаще всего считается неограниченной и не оценивается. Дальше будем говорить в основном о скорости выполнения, но практически все наши определения и рассуждения будут аналогичны и для оценки емкостной сложности алгоритмов.
Время выполнения или требуемая память для одного и того же алгоритма будет разниться в зависимости от конкретных входных данных. Оценить сложность в этом смысле безотносительно параметров невозможно. С другой стороны оценка сложности для каждого набора входных параметров отдельно будет слишком трудоемкой. По-этому, необходимо разделить задачу на группы частных случаев, чтобы оценить сложность для каждой такой группы.
Определение 3.2.1 . Массовая задача - задача с параметрами.
Определение 3.2.2 . Индивидуальная задача - это массовая задача, для всех параметров которой заданы конкретные значения.
Пример 3.2.1 . Например, задача сортировки массива длины n, где не указаны n и значения элементов массива является массовой.
Задача отсортировать массив {8, 10, 4, 5, 1, 3, 7} является
индивидуальной задачей к массовой задаче сортировки.
Для оценки скорости выполнения имеет значение, на каком именно вычислительном устройстве работает алгоритм. В теории сложности алгоритмов различают машины Тьюринга с одной лентой, с k лентами и с произвольным доступом к памяти. Они имеют разные возможности и, следовательно, алгоритмы и время их работы на этих машинах будет различной.
Кроме того, для выбранной машины, реальная длительность выполения данного алгоритма может зависить от быстродействия
машины (длительности выполнения доступных ей операций), что затрудняет использование полученной оценки. По этой причине оценивают не время по абсолютной величине, а число элементарных операций, которые необходимо выполнить при работе данного алгоритма на машине выбранного типа.
Замечание 3.2.1 . На практике не так часто исследуют алгоритм в применении к машинам Тьюринга. Чаще рассматривают возможности некоего обобщенного устройства, понимающего язык высокого уровня. При этом важно помнить, что одна команда высокого уровня может требовать большого количества элементарных операций вычислительной системы.
Также обычно не считают все элементарные операции алгоритма. Обычно выбирается множество ключевых операций, которые оказывают наибольшее влияние на оцениваемую величину. Например, сравнение чисел, обращения к медленной памяти и т.п.
Определение 3.2.3 . Пусть заданы следующие объекты:
массовая задача;
класс индивидуальных задач данной массовой задачи;
алгоритм, решающий эту задачу;
тип машины, на которой будет работать этот алгоритм;
ключевые операции, играющие в алгоритме основную роль.
Сложность алгоритма на этом классе индивидуальных задач - мак- симальное число выделенных ключевых операций, которые выполняет данный алгоритм при решении индивидуальной задачи из выделенного класса; то есть число ключевых операций, которые необходимо выполнить в худшем случае.
Существуют различные подходы к тому, как выбрать класс индивиду- альных задач. Первый способ состоит в том, чтобы зафиксировать один (или несколько) из параметров массовой задачи и разбить ее на такие классы, что в каждый класс входят все задачи с заданным значением этого (этих) параметра. Остальные параметры меняются произвольно в допустимых для них областях. Тогда, сложность алгоритма - функция T (n).
Пример 3.2.2 . Например, массовую задачу сортировки, обычно, разбивают на классы индивидуальных задач по параметру n - длине сортируемого массива. Конкретным классом индивидуальных задач в этом случае могли бы быть все задачи сортировки с массивами длины n = 7.
Второй подход состоит в том, чтобы закодировать условия каждой индивидуальной задачи некоторым "разумным" способом и выбрать в качестве критерия разбиения на классы индивидуальных задач длину N слов, кодирующих задачи, - то есть включать в один класс все индивидуальные задачи, длины кодов которых не превосходят N . Величины сложности на таких классах будут описывать функцию сложности T (N ).
Разумность кодирования здесь подразумевает выбор способа исходя из здравого смысла. Например, не стоит кодировать числа в единичной системе исчисления.
В общем случае и величины фиксированных параметров и длина кода описания задачи характеризуют ее размер и сложность задается функцией от размера.
Часто сложность алгоритма не имеет точного представления формулой над хорошо известными функциями. В этом случае для предъявления функции сложности пришлось бы предъявлять бесконечную таблицу значений. Тогда имеет смысл оценить сложность более простой функцией, например, полиномом некоторой степени.
Введем следующие обозначения (O-символика):
Будем писать f (n) = O(g(n)), если существуют n0 ∈ N и c ∈ R+:
f (n) ≤ c · g(n), ∀n ≥ n0.
Будем писать f (n) = Ω(g(n)), если существуют n0 ∈ N и c ∈ R+:
f (n) ≥ c · g(n), ∀n ≥ n0.
Будем писать f (n) = Θ(g(n)), если существуют n0 ∈ N и c1, c2 ∈ R+:
c1 · g(n) ≤ f (n) ≤ c2 · g(n), ∀n ≥ n0.
Известны следующие свойства: Пусть f и g - функции от натурального аргумента. Тогда
1) f (n) = O(f (n));
2) c · O(f (n)) = O(f (n)), где c - константа;
3) O(f (n)) + O(f (n)) = O(f (n));
4) O(O(f (n))) = O(f (n));
5) O(f (n)) · O(g(n)) = O(f (n) · g(n));
6) O(f (n) · g(n)) = f (n) · O(g(n)).
Если f (n) = O(g(n)) будем говорить, что функция f (n) имеет порядок
O(g(n)).
В реальных ситуациях обычно достаточно выяснить вид функции, наиболее точно ограничивающей сложность алгоритма решения некоторой массовой задачи: полином, логарифм, экспонента и т.п. Если сложность имеет порядок полинома, чаще всего достаточно указать только старшую его степень. Если сложность оценивается экспонентой an, важно основание степени - a.
Пример 3.2.3 . Известны алгоритмы решения задачи сортировки с оценкой сложности O(n · log n).
Какую сложность можно считать практически приемлимой. Рассмотр- им следующую таблицу (рисунок 26), на которой представлено сравне- ние длительности работы алгоритмов разной сложности на некоторой гипотетической машине. По горизонтали отмерены размеры входных параметров, по вертикали - T (n), сложность алгоритмов.
-
T (n)
10
20
30
40
50
60
n
10−5 с
2 · 10−5 с
3 · 10−5 с
4 · 10−5 с
5 · 10−5 с
6 · 10−5 с
n2
10−4 с
0.0004 с
0.0009 с
0.0016 с
0.0025 с
0.0036 с
n3
10−3 с
0.008 с
0.027 с
0.064 с
0.125 с
0.216 с
n5
0.1 с
3.2 с
24.3 с
1.7 мин
5.2 мин
13.0 мин
2n
0.001 с
1.0 с
17.9 мин
12.7 дней
35.7 лет
366 стол
3n
0.059 с
58 мин
6.5 лет
3855 стол
2 · 108 стол
1.3 · 1013 стол
Рисунок 26: Сравнение времени выполнения алгоритмов различной сложности в зависимости от размера параметра.
Как можно видеть, удовлетворительными можно считать только алгоритмы, сложность которых не превосходит некоторого полинома фиксированной (не зависящей от размеров входных параметров задачи) степени. Такие алгоритмы называют полиномиальными. Алгоритмы
экспоненциальной сложности могут быть выполнены за приемлемое время только при небольших размерах входных данных.
Быть может развитие технологий и ускорение вычислительных устройств позволит нам в скором времени выполнять и алгоритмы экспоненциальной сложности. Рассмотрим таблицу на рисунке 27. Там представлены максимальные размеры входных данных гипотетических задач различной сложности, выполняемых за час на одной и той же машине, и на сколько эти размеры могут вырости при ускорении работы компьютеров в 100 и в 1000 раз.
-
T(n)
Современный компьютер
в 100 раз
быстрее
в 1000 раз
быстрее
n
N1
100 · N1
1000 · N1
n2
N2
10 · N2
31.6 · N2
n3
N3
4.63 · N3
10 · N3
n5
N4
2.5 · N4
3.98 · N4
2n
N5
N5 + 6.64
N5 + 9.97
3n
N6
N6 + 4.19
N6 + 6.29
Рисунок 27: Увеличение размера задачи, выполняемой за фиксированное время при увеличении мощности компьютера.
Видно, что в разы увеличивается только размер входных параметров для полиномиальных алгоритмов. Чтобы они могли быть выполненными в то же время, параметры экспоненциальных алгоритмов можно увеличить лишь на единицы.