Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Презентации лекций по ТОИ / 10-Сложность алгоритмов.pps
Скачиваний:
64
Добавлен:
02.06.2015
Размер:
449.02 Кб
Скачать

Пример оценки сложности алгоритма с ветвлениями

Разбиение всего множества комбинаций (в данном случае каждая комбинация определяется только значением переменной X) показано на рисунке:

Рис. Геометрическая вероятность ввода значений переменной, определяемая длинами отрезков числовой прямой

(значения равновероятны)

21

Пример оценки сложности алгоритма с ветвлениями

Таким образом, при выполнении программы возможен выбор трёх ветвей:

1)ветви Y := (X + 0.5) * 2, соответствующей условию X < 0.5, вес (сложность) которой составляет 5 (ввод, проверка условия, вычисление выражения (2 операции) и присваивание), а вероятность выбора равна 0.5;

2)ветви Y := X * 2 + 0.5 + X**3, соответствующей условию

not(X < 0.5) and (X < 0.75), вес (сложность) которой составляет 10 (ввод, проверка условия X < 0.5, проверка условия X < 0.75, вычисление выражения (6 операций) и присваивание), а вероятность выбора равна 0.25; 3) ветви Y := X, соответствующей условию not(X < 0.5) and not(X < 0.75), вес (сложность) которой составляет 4 (ввод, проверка условия X < 0.5, проверка условия X < 0.75, и присваивание), а вероятность её выбора – примерно 0.25.

 

Средняя сложность алгоритма составляет

22

TAvrg = 0,5 5 + 0,25 10 + 0,25 4 = 2,5 + 2,5 + 1 = 6.

 

Оценка алгоритмов, содержащих циклы с предусловием и постусловием

Операторы цикла изображаются в управляющем графе замкнутой последовательностью вершин – циклом. Если выражения, определяющие начальное и конечные значения параметра цикла – константы, то можно посчитать, сколько раз будет выполняться цикл, и умножить это число на вес (сложность) тела цикла. Если число повторений зависит от исходных данных, то необходимо оценить значение разности между начальным и конечным значениями в худшем, лучшем и среднем случаях.

while . . . do . . .

repeat . . . until . . .

 

условие

тело

условие

 

23

тело

 

Оценка алгоритмов, содержащих циклы со счётчиком

Пример 1. Процедура содержит цикл вида

for I := 1 to X do Тело цикла

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

Допустим, что переменная X может принимать значения от 0 до 100 с равной вероятностью (1/101).

Тело цикла выполняется X раз, причём худший случай реализуется при

X = 100, а наилучший – при X = 0.

Среднее число выполнений тела цикла равно

tAvrg = 1/101 0 + 1/101 1 + 1/101 2 + … + 1/101 100 = = 1/101 (0+1+2+…+100) = 1/101 (0+100)/2 101 = 50.

Для более точной оценки оценивается и сложность операций, 24 записанных в заголовке цикла.

Оценка алгоритмов, содержащих циклы со счётчиком

Пример 1. Процедура содержит цикл вида

for I := 1 to X do Тело цикла

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

Допустим, что переменная X может принимать значения от 0 до 100 с равной вероятностью (1/101).

Тело цикла выполняется X раз, причём худший случай реализуется при

X = 100, а наилучший – при X = 0.

Среднее число выполнений тела цикла равно

tAvrg = 1/101 0 + 1/101 1 + 1/101 2 + … + 1/101 100 = = 1/101 (0+1+2+…+100) = 1/101 (0+100)/2 101 = 50.

Для более точной оценки оценивается и сложность операций, 25 записанных в заголовке цикла.

Оценка алгоритмов, содержащих циклы со счётчиком

Пример 2. Процедура содержит вложенные циклы вида for I := 1 to X do

for J := I to X do Тело цикла

Допустим, что переменная X может принимать значения от 1 до 5 с равной вероятностью (1/5).

Внешний цикл выполняется X раз. Тело цикла выполняется

X + (X – 1) + (X – 2) + … + 1 = X (X + 1)/2

раз, причём худший случай реализуется при X = 5, а наилучший – при X = 1. Таким образом, верхняя граница сложности равна X (X+1)/2 = 5 (5+1)/2 = 15. Минимальное число выполнений тела цикла равно X (X+1)/2 = 1 (1+1)/2 = 1.

Среднее число выполнений тела цикла равно

26

Оценка алгоритмов, содержащих циклы со счётчиком

Пример 3. Оценим сложность алгоритма умножения двух квадратных матриц A и B размерностью N N и получения в качестве результата третьей матрицы C:

for I := 1 to N do {Цикл 1}

for J := 1 to N do {Цикл 2} begin

C[I,J] := 0;

for K := 1 to N do {Цикл 3}

C[I,J] := C[I,J] + A[I,K]* A[K,J]

end

В качестве параметра, определяющего сложность данных, в этом случае можно взять N.

27

Оценка алгоритмов, содержащих циклы со счётчиком

Пример 3 (продолжение).

Сложность алгоритма определяется величиной T (N) = N (T1),

где T1 – сложность тела цикла 1 по I, которая равна T1 = N (T2),

где T2 – сложность тела цикла 2 по J равна T2 = 1 + N (T3).

Здесь сложность тела цикла 3 по K (T3) равна 3 (умножение, сложение и присваивание), а 1 операция – это присваивание начального значения элементу матрицы C.

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

28 T (N) = N (N (1 + N 3)) = N (N + N 2 3) = N 2 + N 3 3 = 3N 3 + N 2.

Оценка рекурсивных алгоритмов (простая рекурсия)

Условие, заданное в рекурсивном алгоритме, делит все комбинации

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

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

Операции, которые выполняются при проверке условия (они выполняются

 

всегда).

Операции, выполняемые по нерекурсивной ветви (выполняются один раз –

 

перед выходом из рекурсии, это начало обратного хода рекурсии).

Операции, которые выполняются при выборе рекурсивной ветви (каждый

29

раз, когда проверка условия приводит к рекурсивному вызову). Эти

операции также разбиваются на группы.

Оценка рекурсивных алгоритмов (простая рекурсия)

Операции, которые выполняются при выборе рекурсивной ветви (каждый раз, когда проверка условия приводит к рекурсивному вызову) разбиваются на группы:

операции, понижающие сложность исходных данных при рекурсивном вызове;

операции, выполняемые при рекурсивном вызове с новыми данными, сложность которых стала ниже (это сложность самого рекурсивного алгоритма);

операции, выполняемые каждый раз при выборе этой рекурсивной ветви, но не связанные с рекурсивным вызовом или понижением сложности данных.

30