Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СКТ - 5,6сем.doc
Скачиваний:
5
Добавлен:
01.05.2025
Размер:
8.67 Mб
Скачать

Асимптотический анализ алгоритмов

Кроме использования абстрактной модели вычислений и представления времени работы алгоритма в виде зависимости от размера ввода, упростить анализ можно рассматривая асимптотическую эффективность алгоритмов: т.е. как изменяется время работы алгоритма при возрастании размера ввода до бесконечности. Пусть время работы алгоритма (например, в наихудшем случае) выражается функцией f(n). Нас будет интересовать скорость роста функции f и мы будем ее определять через упрощенную функцию скорости роста T(n).

Например, предположим, что f(n)=an2+bn+c при некоторых константах a, b и с. По мере роста параметра n влияние членов малого порядка будет уменьшаться и ими можно пренебречь, т.е. функцию f(n) можно считать равной an2. Более того, коэффициент а становится сравнительно незначащим при увеличении размера ввода, так что f(n) можно заменить на T(n)=n2.

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

  1. 1 (постоянное время) – такие алгоритмы выполняются за время, независимое от размера ввода.

  2. log n (логарифмическое время) – алгоритмы выполняются путем многократного разбиения задачи на подзадачи фиксированного размера.

  3. n (линейное время) – алгоритмы затрачивают одинаковое время на обработку каждого элемента ввода.

  4. n log n (время, пропорциональное nlogn) – алгоритмы типа “разделяй и властвуй”, которые выполняются путем декомпозиции исходной задачи на более мелкие подзадачи, решения их в отдельности и последующего объединения полученных результатов.

  5. n2 (квадратичное время) – алгоритмы затрачивают постоянное время на обработку всех пар входных элементов.

  6. n3 (кубическое время) – на обработку каждой пары входных элементов затрачивается линейное время.

Асимптотическая нотация представляет удобный язык для описания функций скорости роста.

О - нотация.

Если есть функция f(n), то запись O(f(n)) обозначает множество всех функций, которые растут не быстрее, чем f(n). Функция g(n) принадлежит O(f(n)), если g(n) не более, чем в некоторое постоянное число раз превышает f(n) при достаточно большом n.

Множество g(N)O(f(N)), если для некоторого вещественного числа С существует целое N0, так что g(N)<=C*f(N) , для всех N>=N0.

О - нотация используется для описания верхних оценок алгоритма. Если в худшем случае получена верхняя оценка O(f(n)), то тогда время O(f(n)) достаточно для решения задачи.

Множество g(N)o(f(N)), если для любой константы С существует N0, так что g(N)<=C*f(N) , N>=N0. о-нотация используется для обозначения точных верхних оценок скорости роста функций.

Множество g(N) (f(N)), если для констант С и N0, выполняется g(N)>=C*f(N) , N>=N0 . Используется для нижних оценок скорости роста функций.

Множество g(N)(f(N)), если для констант С1, C2 и N0, выполняется C1f(N)<=g(N)<=C2*f(N) , N>=N0. Используется для функций, скорость роста которых лежит в некоторых пределах.

Анализ рекурсивных алгоритмов

Многие алгоритмы решают большую задачу путем ее декомпозиции на более мелкие подзадачи того же вида, решения их и последующего объединения полученных решений для формирования решения исходной задачи. Такой подход называется рекурсивной декомпозицией.

Алгоритмы, основанные на таком подходе, могут быть проанализированы с использованием рекуррентных отношений.

Например:

При анализе алгоритма, основанного на рекурсивной декомпозиции, мы будем выражать время работы при вводе данных размера n в виде рекуррентного отношения. Например, рассмотрим сортировку путем выборки, при которой выполняется сортировка n целых чисел выделением из набора сначала наименьшего числа, и затем применение этого же алгоритма к оставшимся n-1 числам:

procedure Select(a,n); псевдо-паскаль!!!

begin

if n>0 then begin

i:=positionmin(a,n);

swap(a[0],a[i]);

Select(a+1,n-1);

end;

end.

a - ссылка на начало массива, positionmin возвращает номер минимального числа, время работы процедуры равно (n).

Время работы алгоритма выражается рекуррентным соотношением:

где a и b – константы. T(n-1) соответствует стоимости рекурсивного вызова, an – стоимости обнаружения наименьшего целого числа и взаимного обмена его с a[0] и b – стоимости возврата, если n=0.

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

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

T(n) =T(n-1)+an

=T(n-2)+a(n-1)+an

=T(n-3)+a(n-2)+a(n-1)+an

=T(0)+a+2a+...+(n-1)a+na

=b+ a+2a+...+(n-1)a+na

=b+a(1+2+...+n)

=b+a[n(n+1)/2]

=an2/2+an/2+b

Следовательно, T(n)O(n2).

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