Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГЛАВА_3_15_09.doc
Скачиваний:
6
Добавлен:
14.11.2018
Размер:
142.34 Кб
Скачать

3.2. Сложность алгоритма. Классификация алгоритмов по сложности

Размер задачи r(n) оценивает величину памяти, необходимой для представления исходных данных задачи в ЭВМ.

Однако, возможность представления условия задачи в памяти ЭВМ не гарантирует её практического решения. Во-первых, как правило, нужна дополнительная память для хранения промежуточных и окончательных результатов счёта.

Во–вторых, время решения может оказаться недопустимо большим. И первое условие и второе зависят от алгоритмов, применяемых при решении задачи.

Размер дополнительной памяти, как правило, определить несложно. Рассмотрим время счёта. В процессе реализации расчётного алгоритма, выбранного для решения задачи, необходимо выполнять определённое число элементарных арифметических, логических и других операций – сложения, вычитания, умножения, деления, возведения в степень, сравнения и т. д.

Пусть в процессе решения задачи при помощи некоторого алгоритма выполняются элементарные операции с номерами 1, 2, ..., k. Среднее время выполнения этих операций на используемой ЭВМ обозначим через t1, ... , tk , число операций, зависящее от применяемого алгоритма решения – через g1(n), ... , gk(n).

Обозначим полное время счёта алгоритма через Т(n). Достаточно точно его можно выразить в виде суммы: Т(n) = Т1(n) + Т2(n)+...+Тk(n), где Т1(n), Т2(n), ...k(n) – общее время выполнения каждой из операций 1,2,...,k. Выражая все величины Тi(n) через ti и gi(n), получим:

Рассмотрим зависимость скорости роста общего времени счета алгоритма Т(n) от чисел выполняемых операций g1(n) – gk(n).

Теорема 3.1 о скорости роста времени счета алгоритма. Пусть при выполнении алгоритма используются элементарные операции 1, 2, ... , k. У операции с номером s (1  sk) число выполняемых операций gs(n) имеет устойчивую скорость роста fs(n). У остальных операций i (1  i k , i s) числа выполняемых действий gi(n) ограничены сверху функциями со скоростями роста, меньшими fs(n).

Тогда при n→∞ скорость роста общего времени счёта алгоритма Т(n) будет устойчивой и равна скорости роста fs(n) независимо от среднего времени выполнения t1 , ... , tk элементарных операций f1(n), ... , fk(n).

Доказательство. Представим общее время счета алгоритма Т(n) в следующем виде:

У операции s для числа выполняемых действий gs(n) по определению одинаковой скорости роста с fs(n) существуют такие значения n0sN, С1s>0, С2s >0 , что при  n n0s выполняется условие: С1s fs (n) ≤ gs (n) ≤ С2s fs (n).

Рассмотрим остальные операции i (1  i k , i s). Очевидно, gi (n)  0. По определению ограниченности сверху для любой операции i существуют такие значения n0i N, С2i >0 , что при  n n0i выполняется условие: gi (n) ≤ С2i fi (n).

Принимая:

зависимость всех пар функций gi(n), fi(n) при  n n0 можно представить в унифицированном виде: gi (n) ≤ С2 fi (n) , а для общего времени счета – записать неравенство:

Поскольку все скорости роста fi (n) при i s меньше скорости роста fs (n), то по определению для константы С=1 всегда найдется такое значение параметра n0i N, что при n n0i справедливо: fi(n) ≤ fs(n). Принимая в качестве n0 = max(n0, n01, … , nik), получим, что при  n n0 правое неравенство может быть представлено в виде:

Вводя новые константы:

получим, что при  n n0 выполняется соотношение, доказывающее справедливость теоремы:

С1 fs (n) ≤ T(n) ≤ С2 fs (n),

т.е. одинаковую скорость роста у общего времени счета T(n) и у максимальной из скоростей роста числа элементарных операций алгоритма, что и требовалось доказать.

При анализе элементарных арифметических операций алгоритма и подсчете их числа необходимо учитывать тип величин, с которыми выполняются данные действия. Представление целых и вещественных чисел в памяти ЭВМ различно. Операции с целыми числами в процессоре выполняет арифметико-логическое устройство, а операции с вещественными числами - сопроцессор для чисел с плавающей запятой.

Замечания. 1. Одинаковая скорость роста числа выполняемых операций может быть у нескольких элементарных операций. Справедливость доказанного утверждения при этом сохраняется.

2. Если у максимально растущих чисел операций gi(n) скорость роста не является устойчивой, а известна лишь верхняя ее оценка, то справедлив следующий вариант теоремы 3.1.

Теорема 3.2 о верхней оценке скорости роста времени счета алгоритма. Пусть при выполнении алгоритма используются элементарные операции 1, ... , k. Числа этих операций g1(n), … , gk(n) ограничены сверху скоростью роста функции f(n).

Тогда при n→∞ скорость роста общего времени счёта алгоритма Т(n) также будет ограничена сверху скоростью роста функции f(n).

Доказательство Теоремы 3.2 можно выполнить по аналогии с доказательством Теоремы 3.1.

Следствие. Скорость роста общего времени счёта алгоритма Т(n) определяется скоростями роста f1(n), ... , fk(n) чисел элементарных операций g1(n), ... , gk(n) либо их верхними границами.

Скорость роста общего времени счёта алгоритма Т(n) называют сложностью алгоритма и обозначают через f(n).

В зависимости от сложности все комбинаторные алгоритмы делятся на несколько основных групп.

Полиномиальными называются алгоритмы, сложность которых ограничена полиномом.

Примеры 1: а) f(n) = n, б) f(n) = n 2, в) f(n) = nlogn < n 2.

Экспоненциальными называются комбинаторные алгоритмы, сложность которых в пределе при бесконечном возрастании n превышает полином любой степени.

Примеры 2: а) f(n) = е n, б) f(n) = n n, в) f(n) = n!, г) f(n) = 2 n.

Субэкспоненциальными называются алгоритмы, сложность которых в пределе при бесконечном возрастании n превышает полином любой степени, но меньше 2 nδ при любом δ>0.

Пример 3. f(n) = n logn.

Рассмотрим примеры расчета сложности алгоритмов.

Пример 4. Задача: упорядочить по убыванию элементов линейный числовой массив А[n]i.

Предлагаемый алгоритм решения: внутренняя (без использования дополнительной памяти) сортировка с выбором. В данном алгоритме выполняется n –1 шаг. На первом определяется минимальный из n элементов a1, a2, … , an и путем обмена с a1 помещается на первое место. На втором определяется минимальный из n–1 элементов a2, … , an и путем обмена с a2 помещается на второе место и т.д.

Необходимо определить сложность алгоритма как функцию характерного числа задачи, которым является длина массива n.

Решение. В алгоритме используются две основные операции – 1) сравнение величин элементов массива и 2) обмены пар элементов местами. Определим в зависимости от параметра задачи n числа выполняемых основных операций. Обозначим их, соответственно, g1(n) и g2(n). Так как всего выполняется n 1 шаг, на каждом один обмен, то g2(n) = n – 1. На первом шаге выполняется (n - 1) сравнение, на втором – (n 2), … , на последнем (n – 1) –том – одно сравнение. g1(n) определяем как сумму арифметической прогрессии:

g1(n) = (n – 1)+ (n 2)+…+1 = n(n - 1)/2.

Так как для найденных функций выполняются следующие предельные оценки:

то по определению g1(n) имеет квадратичную полиномиальную скорость роста, а g2(n) – линейную.

Ответ: поскольку у операции сравнения 1 устойчивая квадратичная полиномиальная скорость роста, а у операции обмена 2 – устойчивая линейная скорость, то по Теореме 3.1 скорость роста общего времени счёта (сложность) алгоритма будет устойчивой и равна максимальной из скоростей роста чисел элементарных операций, т.е. будет квадратичной полиномиальной.

Пример. 5. Необходимо определить сложность алгоритма, заключающегося в полном переборе обходов в задаче коммивояжера (ЗК) для n населенных пунктов {vn }={v1, v2, ... , vn}(пример 5 п.3.1).

Решение. На каждом из (n–1)!/2 возможных обходов при полном переборе требуется выполнить следующие операции:

1) сформировать сам обход Оn={vi1, vi2, ... , vin} ,

2) вычислить длину обхода {vi1, vi2, ... , vin} L(Оn):

3) сравнить длину обхода L(Оn) с текущим значением минимума Lmin и при необходимости – скорректировать Lmin.

Поскольку формирование обхода Оn требует n элементарных операций, вычисление длины – также n сложений, то числа выполняемых операций g1(n) (формирование обхода), g2(n) (сложение), g3(n) (сравнение длин обхода) будут следующими:

g1(n)= n! /2, g2(n)= n! /2, g3(n)= (n–1)!/2 .

Для найденных функций выполняются следующие предельные оценки:

По Теореме 3.1 сложность алгоритма будет устойчивой и равна максимальной из скоростей роста чисел элементарных операций, т.е. будет факториальной по n.

Ответ: Сложность алгоритма относится к экспоненциальному типу.

Сравнительные значения величин функций для трёх рассмотренных типов скоростей роста при значениях характерного параметра n = 10, 100, 1000 приведены в таблице.

NN Вид алгоритма Функция n = 10 n =100 n = 1000

n 1 10 102 103

nlogn 10 2102 3103

1. Полиномиальный n 2 102 104 106

n 3 103 106 109

n10 1010 1020 1030

2. Субэкспоненциальный nlnn 200,7 1,621013 5,291029

еn 0.22105 0.271043 0.7810208

3. Экспоненциальный 2n 0.1104 0.121031 0.110301

n! 0.36 107 10158 4102567

nn 1010 10200 103000

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]