Лекция 1: Введение в алгоритмы

Preview:

Citation preview

Лекция 1:

Введение в алгоритмы

Курносов Михаил Георгиевич

к.т.н. доцент Кафедры вычислительных систем

Сибирский государственный университет

телекоммуникаций и информатики

http://mkurnosov.net/teaching

Литература

2

1. [CLRS] Кормен Т.Х., Лейзерсон Ч.И., Ривест Р.Л., Штайн К.

Алгоритмы: построение и анализ. – 2-е изд. – М.: Вильямс, 2005. –

1296 с.

2. Левитин А.В. Алгоритмы: введение в разработку и анализ. – М.:

Вильямс, 2006. – 576 с.

3. Ахо А.В., Хопкрофт Д., Ульман Д.Д. Структуры данных и

алгоритмы. – М.: Вильямс, 2001. – 384 с.

4. Седжвик Р. Фундаментальные алгоритмы на С++.

Анализ/Структуры данных/Сортировка/Поиск. – К.: ДиаСофт, 2001.

– 688 с.

5. Макконнелл Дж. Основы современных алгоритмов. – 2е изд. – М.:

Техносфера, 2004. – 368 с.

6. Скиена С.С. Алгоритмы. Руководство по разработке. – 2-е изд. –

СПб: БХВ, 2011 – 720 с.

7. Керниган Б.В., Пайк Р. Практика программирования. – СПб.:

Невский Диалект, 2001. – 381 с.

Понятие алгоритма

3

Алгоритм (algorithm) – это конечная последовательность

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

которой обеспечивается получение требуемого результата из

исходных данных.

Уточнения

Алгоритм должен описываться на формальном языке

исполнителя, исключающем неоднозначность толкования.

Множество инструкций конечно.

Запись алгоритма на формальном языке называется программой.

Свойства алгоритмов

4

Дискретность – алгоритм представляется как последовательность

инструкций исполнителя. Каждая инструкций выполняется только после

того, как закончилось выполнение предыдущего шага.

Конечность (результативность, финитность) – алгоритм должен

заканчиваться после выполнения конечного числа инструкций.

Массовость – алгоритм решения задачи должен быть применим для

некоторого класса задач, различающихся лишь значениями входных

данных.

Детерминированность (определенность) – каждый шаг алгоритма

должен быть точно определен – записан на формальном языке

исполнителя. Детерминированность обеспечивает одинаковость

результата, получаемого при многократном выполнении алгоритма, на

одном и том же наборе входных данных.

Пример

5

Задан массив h[n], содержащий рост каждого студента 1-го курса. Требуется

разработать алгоритм поиска студента k с максимальным ростом.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

180 155 193 176 159 169 172 195 201 160 167 180 177 174 179 187 166 193 183 175 169 170 157 199 187

h[25]:

k = 8

algorithm MaxHeight(h, n)

hmax = 0

for i = 0 to n – 1 do

if h[i] > hmax then

hmax = h[i]

k = i

end if

end for

return k

end algorithm

Свойства алгоритма:

Дискретность?

Конечность?

Массовость?

Детерминированность?

Показатели эффективности алгоритмов

6

1. Время выполнения (execution time) – временная

эффективность

2. Объем потребляемой памяти (memory consumption) –

пространственная эффективность

3. Объем потребляемой электроэнергии (energy consumption)

Анализ времени выполнения алгоритмов

7

Что влияет на время выполнения алгоритма

(программы)?

1. Размер входных данных.

2. Качество реализации алгоритма на языке

программирования.

3. Качество скомпилированного кода.

4. Производительность вычислительной машины.

Для многих алгоритмов время их выполнения в

больше степени зависит не от самих значений

входных данных, а от их размера (например,

не от значений элементов массива, а от его длины).

Входные данные

Алгоритм

(программа)

Вычислительная

машина

Компилятор,

интерпретатор

Анализ времени выполнения алгоритмов

8

У каждого алгоритма есть параметры, определяющие размеры

его входных данных

Поиск минимума в массиве: n – количество элементов

в массиве

Умножения матриц: n, m – количество строки и столбцов

в матрице

Сравнения двух строк: s1, s2 – длина первой и второй строк

Поиск кратчайшего пути в графе между двумя вершинами:

n, m – количество вершин и ребер в графе

Анализ времени выполнения алгоритмов

9

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

количества “базовых операций” выполняемых им – как функцию от

размера входных данных

Принимаются следующие допущения о гипотетической

вычислительной машине (исполнителе):

для выполнения “простой” операции (+, - , *, /, =, if, call) требуется

один временной шаг (такт вычислительной машины)

обращение к памяти (чтение, записи) выполняется за один

временной шаг

циклы и подпрограммы состоят из последовательности простых

операций

Поиск минимального элемента в массиве

10

1 algorithm MaxHeight(h, n)

2 hmax = 0

3 for i = 0 to n – 1 do

4 if h[i] > hmax then

5 hmax = h[i]

6 k = i

7 end if

8 end for

9 return k

Вычислим количество T(n) операций, выполняемых алгоритмом поиска

максимального элемента в массиве.

Результат условного ветвления заранее

неизвестен. Оцениваем по худшему

случаю (worst case) – условие

выполняется всегда.

if – 1 такт

cравнение h[i] > hmax – 1 такт

T(n) = 1 + (2 + 2)n + 1 = 2 + 4n

Количество T(n) операций, выполняемых алгоритмом в худшем случае:

Сортировка массива методом “пузырька”

11

Algorithm BubbleSort(v[1:n], n)

for i = 1 to n – 1 do

for j = n to i + 1 do

if v[j - 1] > v[j] then

temp = v[j - 1]

v[j - 1] = v[j]

v[j] = temp

end if

end for

end for

Оценим количество T(n)

операций, выполняемых

алгоритмом в худшем случае.

2 + 2 + 2 + 1 = 7 операций

Сколько раз выполняется цикл?

Цикл 2 выполняется n – 1 раз:

n to 2, n to 3, …, n to n – 1

Суммарное количество итераций цикла 2:

T(n) = (n – 2 + 1) + (n – 3 + 1) + …+ (n – n + 1) =

(n – 1) + (n – 2) + … + 1 = ? =

+

= + −

− =

=

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

12

Вычислительная сложность алгоритма (computational complexity) –

это оценка количества операций выполняемых алгоритмом в зависимости

от размера его входных данных.

При асимптотическом анализе вычислительной сложности алгоритма

(asymptotic computational complexity) рассматривается поведение

алгоритма при n → ∞.

Причины:

1. Точное значение временной сложности зависит от определения

элементарных операций исполнителя (например, сложность можно

измерять в количестве арифметических операций, битовых операций или

операций на машине Тьюринга).

2. При увеличении размера входных данных (n → ∞) вклад постоянных

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

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

13

Имеется два алгоритма:

T1(n) = 95n2 + 405n + 1997

T2(n) = 2n3 + 12

Какой алгоритм предпочтительнее при увеличении n?

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

14

T1(n) = 95n2 + 405n + 1997

T2(n) = 2n3 + 12

T(n)

n

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

15

При асимптотическом анализе вычислительной сложности алгоритма

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

наихудший случай (worst case) – максимальное количество операций,

требуемых для обработки набора входных данных;

средний случай (average case) – среднее количество операций,

требуемых для обработки набора входных данных;

наилучший случай (best case) – минимальное количество операций

требуемых для обработки набора входных данных.

Для записи асимптотической сложности алгоритмов используются

асимптотические обозначения – О-нотацию (Big O).

Асимптотические обозначения

16

Обозначим через f(n) количество операций выполняемых алгоритмом.

f(n) = O(g(n)) – означает, что функция f(n) ограничена сверху

функцией c·g(n). Формально: существуют положительные константы

c и n0 такие, что f(n) ≤ c·g(n) для всех n ≥ n0 (c > 0, n0 > 0).

f(n) = Θ(g(n)) – означает, что функция f(n) ограничена сверху

функцией c1·g(n), а снизу функцией c2·g(n). Формально: существуют

положительные константы c1, c2 и n0 такие, что c2·g(n) ≤ f(n) ≤ c1·g(n)

для всех n ≥ n0.

f(n) = Ω(g(n)) – означает, что функция f(n) ограничена снизу функцией

c·g(n). Формально: существуют положительные константы c и n0 такие,

что f(n) ≥ c·g(n) для всех n ≥ n0.

Асимптотические обозначения

17

nn0

cg(n)

f(n)

O-большое

nn0

cg(n)

f(n)

Θ-большое

nn0

c1g(n)

f(n)

Ω-большое

c2g(n)

Примеры

3n2 – 100n + 6 = O(n2)

1. Вычислительная сложность алгоритма поиска минимального элемента в массиве:

T(n) = 1 + (2 + 2)n + 1 = 2 + 4n T(n) = O(n) – линейная относительно n.

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

=7

2−7

2T(n) = O(n2) .

Свойства O, Θ, Ω

18

1. O(f(n)) + O(g(n)) = O(max(f(n), g(n)))

Пример: n3 + n2 + n + 1 = O(n3)

2. O(c·f(n)) = O(f(n))

Пример: O(4n3) = O(n3)

3. O(f(n)) * O(g(n)) = O(f(n) * g(n))

Пример: O(n3) * O(n) = O(n4)

Основные классы сложности

19

Класс сложности Название

O(1) Константная сложность

O(logn) Логарифмическая сложность

O(n) Линейная сложность

O(nlogn) n-log-n сложность

O(n2) Квадратичная сложность

O(n3) Кубическая сложность

O(2n) Экспоненциальная сложность

O(n!) Факториальная сложность

Пространственная эффективность

20

Algorithm BubbleSort(v[1:n], n)

for i = 1 to n – 1 do

for j = n to i + 1 do

if v[j - 1] > v[j] then

temp = v[j - 1]

v[j - 1] = v[j]

v[j] = temp

end if

end for

end for

Какова сложность по памяти алгоритма сортировки методом “пузырька”?

Tmem = O(1)

Задание

21

Познакомится с определениями (учебники, to google):

Рандомизированные алгоритмы (randomized algorithm).

Вычислительная сложность алгоритма (computational complexity)

О-нотация (big O)

Прочитать:

Aho, с.28-37.

Sedgewick, с. 42-55.

Recommended