- •Содержание
- •Введение.
- •1. Основы анализа алгоритмов
- •1.1. Сравнительные оценки алгоритмов
- •1.2. Элементарные операции в формальной системе
- •1.3. Классы входных данных
- •1.4. Классификация алгоритмов по виду функции трудоемкости
- •1.5. Классификация скоростей роста. Асимптотический анализ функций
- •1. Оценка (тета)
- •2. Оценка о (о большое)
- •3. Оценка (Омега)
- •1.6. Эффективность рекурсивных алгоритмов
- •1.7. Анализ программ
- •1.8. Вопросы для самоконтроля
- •Классификация алгоритмов по виду функции трудоемкости.
- •2. Алгоритмы поиска и выборки
- •2.1. Последовательный поиск
- •2.2. Двоичный поиск
- •2.3. Задача выборки
- •2.4. Вопросы для самоконтроля
- •3.Алгоритмы сортировки
- •3.1. Сортировка трех чисел по месту
- •3.2. Сортировка вставками
- •3.3. Пузырьковая сортировка
- •3.4. Сортировка Шелла.
- •3.5. Корневая сортировка
- •3.6. Сортировка методом индексов
- •3.7. Быстрая сортировка (алгоритм Хоара)
- •3.8. Вопросы для самоконтроля
- •Сортировка Шелла.
- •Сортировка методом индексов.
- •4. Алгоритмы на графах
- •4.1. Основные понятия теории графов
- •4.2. Структуры данных для представления графов
- •4.3. Алгоритмы обхода вершин графа
- •4.3.1. Обход в глубину
- •4.3.2. Обход в ширину
- •4.4. Поиск остовного дерева минимального веса
- •4.4.1. Алгоритм Дейкстры – Прима
- •4.4.2. Алгоритм Крускала
- •4.5. Алгоритм поиска кратчайшего пути
- •4.6. Вопросы для самоконтроля
- •Структуры данных для представления графов.
- •5. Численные методы
- •5.1. Вычисление значений многочленов
- •5.2. Умножение матриц
- •5.2.1 Стандартный алгоритм умножения матриц
- •5.2.2. Умножение матриц по Винограду
- •5.2.3. Умножение матриц по Штрассену
- •5.3. Вопросы для самоконтроля
- •Стандартный алгоритм умножения матриц.
- •6. Алгоритмы сравнения с образцами
- •6.1. Сравнение строк
- •6.2. Алгоритм Кнута – Морриса – Пратта
- •6.3. Алгоритм Бойера - Мура
- •6.4. Вопросы для самоконтроля
- •7. Вычислительная геометрия
- •7.1. Основные понятия
- •7.2. Векторное произведение векторов
- •7.2.1. Ориентированная площадь треугольника
- •7 .3. Задача о выпуклой оболочке
- •7.3.1. Алгоритм Грэхема
- •7.3.2. Алгоритм Джарвиса
- •7.3.3. Рекурсивный алгоритм
- •7.4. Вопросы для самоконтроля
- •8. Задачи класса np
- •8.1. Примеры np-полных задач
- •8.1.1. Задача о коммивояжере
- •8.1.2. Задача о раскраске графа
- •8.1.3. Раскладка по ящикам
- •8.1.4 Упаковка рюкзака
- •8.1.5. Задача о суммах элементов подмножества
- •8.1.6. Задача о планировании работ
- •8.2. Приближенные эвристические решения nр-полных задач.
- •8.2.1. Жадные приближенные алгоритмы
- •8.2.2. Приближения в задаче коммивояжера
- •8.2.3. Приближения в задаче о раскладке по ящикам
- •8.2.4. Приближения в задаче об упаковке рюкзака
- •8.3. Вопросы для самопроверки
- •Приближения в задаче об упаковке рюкзака.
- •9. Динамическое программирование
- •Часть1--------------------
- •10. Метод ветвей и границ
- •Вопросы к зачету
- •Классификация алгоритмов по виду функции трудоемкости.
- •Приближения в задаче об упаковке рюкзака.
- •Динамическое программирование
- •Метод ветвей и границ. Литература
1.4. Классификация алгоритмов по виду функции трудоемкости
В зависимости от влияния исходных данных на функцию трудоемкости алгоритма может быть предложена следующая классификация, имеющая практическое значение для анализа алгоритмов:
1. Количественно-зависимые по трудоемкости алгоритмы
Это алгоритмы, функция трудоемкости которых зависит только от размерности конкретного входа, и не зависит от конкретных значений:
fА (D) = fА (|D|) = fА (N)
Примерами алгоритмов с количественно-зависимой функцией трудоемкости могут служить алгоритмы для стандартных операций с массивами и матрицами – умножение матриц, умножение матрицы на вектор и т.д.
2. Параметрически-зависимые по трудоемкости алгоритмы
Это алгоритмы, трудоемкость которых определяется не размерностью входа (как правило, для этой группы размерность входа обычно фиксирована), а конкретными значениями обрабатываемых слов памяти:
fА (D) = fА (d1,…,dn) = fА (P1,…,Pm), m n
Примерами алгоритмов с параметрически-зависимой трудоемкостью являются алгоритмы вычисления стандартных функций с заданной точностью путем вычисления соответствующих степенных рядов. Очевидно, что такие алгоритмы, имея на входе два числовых значения – аргумент функции и точность, выполняют существенно зависящее от значений количество операций.
а) Вычисление xk последовательным умножением fА (x, k) = fА (k).
б) Вычисление ex=(xn/n!), с точностью до fА = fА (x, )
3. Количественно-параметрические по трудоемкости алгоритмы
Однако в большинстве практических случаев функция трудоемкости зависит как от количества данных на входе, так и от значений входных данных, в этом случае:
fА (D) = fА (|D|, P1,…,Pm) = fА (N, P1,…,Pm)
В качестве примера можно привести алгоритмы численных методов, в которых параметрически-зависимый внешний цикл по точности включает в себя количественно-зависимый фрагмент по размерности.
3.1 Порядково-зависимые по трудоемкости алгоритмы
Среди разнообразия параметрически-зависимых алгоритмов выделим еще одну группу, для которой количество операций зависит от порядка расположения исходных объектов.
Пусть множество D состоит из элементов (d1,…,dn), и |D|=N,
Определим Dp = {(d1,…,dn)} как множество всех упорядоченных N-ок из d1,…,dn, отметим, что |Dp|=n!.
Если fА (iDp) fА (jDp), где iDp, jDp Dp, то алгоритм будем называть порядково-зависимым по трудоемкости.
Примерами таких алгоритмов могут служить ряд алгоритмов сортировки, алгоритмы поиска минимума и максимума в массиве.
1.5. Классификация скоростей роста. Асимптотический анализ функций
Как было отмечено выше, точное знание количества операций, выполненных алгоритмом, не играет существенной роли в анализе алгоритма для больших размерностей входа. Куда более важной оказывается скорость роста этого количества при возрастании объема входных данных. Она называется скоростью роста функции трудоемкости алгоритма.
На рис. 1.1 приведено несколько графиков различных функций.
у
х2/8
160
140
120
100 3х
80
60
40 х+10
20
2log x
2 6 10 14 18 22 26 30 х
Значение функции зависит от того, большие или малые значения аргумента мы рассматриваем.
Например, в точке x = 2, наименьшее значение y функции x2/8, а максимальное – у функции (х+10). Однако с ростом х функция x2/8 становится и остается впоследствии наибольшей.
В таблице 1 приведены некоторые часто встречающиеся классы функций (и, соответствующие классы скорости роста).
Таблица 1. Классы скорости роста функций
n |
log2 n |
n |
|
n log2 n |
n2 |
n3 |
2n |
n! |
1 2 5 10 15 20 30 40 |
0 1.0 2.3 3.3 3.9 4.3 4.9 5.3 |
1 2 5 10 15 20 30 40 |
1 1.4 2.23 3.16 3.87 4.47 5.47 6.32 |
0 2.0 11.6 33.2 58.6 86.4 147.2 212.9 |
1 4 25 100 225 400 900 1600 |
1 8 125 1000 3375 8000 27000 64000 |
2 4 32 1024 32768 1048576 1073741824 |
1 2 120 3628800 1307674368000 …………………. |
Из таблицы видно, что при небольших размерах входных данных значения функций отличаются незначительно, однако при росте этих размеров разница существенно возрастает. На малых объемах принципиальная разница оказывается скрытой, поэтому и проводят сравнения для больших объемов.
Данные рисунка и таблицы иллюстрируют еще одно свойство функций: быстрорастущие функции доминируют функции с более медленным ростом.
Если мы обнаружим, что сложность алгоритма представляет собой сумму двух или несколько функций, то часто отбрасывают все функции, кроме тех, которые растут быстрее всего.
Например, если установлено при анализе алгоритма, что он делает x3 + 30x операций, то говорят, что сложность алгоритма растет как x3. Причина этого в том, что уже при х=100, разница между х3 и (х3+30х) составляет всего лишь 0,3%.
Таким образом, при анализе алгоритма рассматривается общий характер поведения алгоритма, а не подробности этого поведения. Нас, скорее, будет интересовать класс скорости роста, к которому относится алгоритм, нежели точное количество выполняемых операций каждого типа.
При анализе поведения функции трудоемкости алгоритма часто используют принятые в математике асимптотические обозначения, позволяющие показать скорость роста функции, маскируя при этом конкретные коэффициенты.
Такая оценка функции трудоемкости алгоритма называется сложностью алгоритма и позволяет определить предпочтения в использовании того или иного алгоритма для больших значений размерности исходных данных.
В асимптотическом анализе приняты следующие обозначения [1]: