Лекция. Анализ эффективности нерекурсивных алгоритмов Заикин Олег Сергеевич zaikin.icc@gmail.com zaikin.all24.org Экзамен Экзамен будет проходить в компьютерном классе. В билете 2 вопроса: 1 из раздела «Алгоритмы и структуры данных» и 1 из раздела «Программирование». При ответе на вопрос из раздела «Программирование» нужно быть готовым написать исходный код программы, поясняющий ответ на вопрос. Вопросы к экзамену Алгоритмы и структуры данных 1. Алгоритм, свойства алгоритма, связь между алгоритмом и программой. 2. Структуры, перечисления, объединения. 3. Указатели. Арифметика указателей. 4. Массивы. Статические/динамические. Одномерные/многомерные. 5. Связные списки. Односвязный, двусвязный, кольцевой. Добавление, удаление, поиск элементов. 6. Стек, дек, очередь с приоритетом. 7. Объект и класс. Инкапсуляция и наследование классов. 8. Шаблоны функций, шаблоны классов. 9. Метод грубой силы. Сортировка выбором, пузырьковая. 10. Метод декомпозиции. Сортировка слиянием. 11. Метод уменьшения размера задачи. Быстрая сортировка, сортировка вставкой. 12. Анализ эффективности нерекурсивных алгоритмов. Вопросы к экзамену Программирование 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Язык программирования, программа, исходный код, компиляция, компоновка. Потоки ввода/вывода, условное выражение, условные оператор, виды циклов, инструкции перехода, инструкция выбора. Виды ошибок, отладка и тестирование программ. Функции. Локальные и глобальные переменные. Передача аргументов в функцию. Прототипы функций. Указатели, арифметика указателей. Использование указателей для работы с массивами. Файловые потоки, считывание массива из файла. Низкоуровневые строки (char*). Высокоуровневые строки (string). Строковые потоки (stringstream), преобразование типов через строковые потоки. Объект и класс. Инкапсуляция. Конструкторы и деструкторы классов. Наследование классов. Перегрузка операторов класса. Шаблоны классов, шаблоны функций. STL: контейнер, итератор, алгоритм. Виды эффективности Эффективность алгоритма: Временная (индикатор скорости работы алгоритма) Пространственная (сколько для алгоритма требуется оперативной памяти) В основном анализируется временная эффективность. Оценка размера входных данных Временная эффективность (далее просто эффективность) напрямую зависит от размера входных данных. Эффективность можно задать функцией от некоторого параметра, связанного с размером входных данных. Пример: Эффективность алгоритма решения задачи сортировки списка зависит от размера списка Оценка размера входных данных Для некоторых задач можно брать разные параметры входных данных. Пример: Задача перемножение двух матриц размером n на n. 1-ый вариант параметра - это порядок матрицы n 2-ой вариант - число N =n*n элементов в матрице Оценка размера входных данных В случае, если на вход алгоритму подается целое число n, принято оценивать размер входных данных по количеству битов b в двоичном представлении числа n. b = log 2 n + 1 Например, для алгоритма возведения целого числа n в квадрат значение эффективности одинаково для чисел 9 и 14 (т.к. число битов двоичного представления этих чисел одно и то же). Единицы измерения времени В качестве единицы измерения времени выполнения алгоритма принято использовать не секунды, минуты и пр., а количество операций, выполняемых алгоритмом. При этом считаются не все операции, а лишь основные (которые вносят наибольший вклад в общее время выполнения алгоритма). При анализе эффективности алгоритма необходимо определить, какие операции в нем основные. Единицы измерения времени Примеры В большинстве алгоритмов сортировки основной операцией является сравнение. В алгоритме умножения матриц используются операции сложения и умножения, основной является умножения, т.к. на компьютерах оно выполняется дольше, чем сложение. Упражнения Для каждого из алгоритмов определите 1) естественные единицы измерения входных данных 2) основную операцию алгоритма 3) будет ли изменяться количество основных операций на разных входных данных одинакового размера а) вычисление суммы n чисел б) вычисление n! в) поиск наибольшего элемента в списке из n чисел г) алгоритм умножения в столбик двух n-разрядных десятичных целых чисел Единицы измерения времени Пусть c – время выполнения основной операции алгоритма, а C(n) – количество раз, которые эта операция должна быть выполнена при работе алгоритма. Время выполнения программы T(n) определяется по формуле T n c Cn Данная формула позволяет определить, на сколько изменится время выполнения алгоритма при изменении размера входных данных. Единицы измерения времени Пусть C n 1 2 n 2 . Если удвоить размер входных данных, то время выполнения алгоритма увеличится в 4 раза, т.к. 1 ( 2n) 2 T 2n c C 2n 2 4 1 T n c C n n2 2 Заметим, что ответ не зависит от c, поэтому при анализе эффективности алгоритмов сосредотачиваются на оценке порядка роста количества основных операций с точностью до постоянного сомножителя. Упражнения а) Сложение двух матриц размером n на n б) Умножение двух матриц размером n на n. 1) Назовите основную операцию 2) Определите зависимость количества основных операций как функцию от порядка матрицы. 3) Определите зависимость количества основных операций как функцию от числа элементов в матрице. Упражнения Для решения системы из n уравнений (n – произвольное целое число), используется алгоритм последовательного исключения Гаусса, в котором 3 n выполняется 3 умножений, являющихся основной операцией алгоритма. а) Определите, во сколько раз дольше будет работать алгоритм Гаусса для решения системы из 1000 уравнений в сравнений со временем решения из 500 уравнений б) Компьютер 1 быстрее в 1000 раз компьютера 2. Определите, на сколько порядков бОльшую систему уравнений сможет решить за одно и то же время компьютер 1. Сложность алгоритмов в разных случаях В большом количестве алгоритмов время выполнения зависит не только от размера входных данных, но и от особенностей конкретных входных данных. Пример. Задача последовательного поиска (поиск заданного элемента k в списке длиной n). В наихудшем случае (когда заданного элемента в списке нет) будет выполнено n операций сравнения. В наилучшем – будет выполнено 1 сравнение. Сложность алгоритмов в разных случаях Сложность алгоритма в наихудшем (наилучшем) случае – сложность для таких входных данных, на которых время работы алгоритма будет наибольшим (наименьшим). Упражнения В ящике хранится 22 перчатки: 5 пар красных, 4 пары желтых и 2 пары зеленых. Предположим, что вы выбираете их в темноте наугад и можете проверить, что именно вы выбрали, только после того, как выбор сделан. Чему равно минимальное количество перчаток, которое надо взять из ящика, чтобы получить как минимум одну пару перчаток (т.е. левая + правая) одинакового цвета? а) Дайте ответ на этот вопрос для наилучшего и наихудшего случая. б) Дайте ответ для наилучшего и наихудшего случая для варианта, в котором нужно получить как минимум две перчатки одинакового цвета (не обязательно пару) Классы сложности Факт lim n f n C g n где С - константа обозначается так: f x Og x , это значит что функции f(x) и g(x ) имеют один и тот же порядок роста. Классы сложности Класс Название 1 n Константная Линейная Квадратичная Кубическая n2 n3 2n n! Экспоненциальная Факториальная Запись f x Og x означает, что f(x) относится к классу сложности g(x), а также, что f(x) имеет соответствующий порядок роста (например, линейный) Классы сложности На практике при поиске класса сложности можно отбрасывать слагаемые, которые представляют функции меньшего порядка роста. Примеры: а) 5n + 3 = O(n), т.к. nlim 5 n 3 5 n 3 n lim lim 5 lim 5 n n n n n n n n n 1 O n 2 , т.к. 2 n n 1 2 1 n2 n 1 1 1 lim lim lim 1 2 2 n n n n 2 n 2 n 2 б) Упражнения Для каждой из приведенных ниже функций укажите порядок роста и класс сложности. а) n 2 110 б) 10n 2 7 n 3 в) 2 n 1 3n 1 Анализ нерекурсивных алгоритмов Общий план анализа сложности нерекурсивных алгоритмов: 1. Выберите параметр (или параметры), по которому будет оцениваться размер входных данных алгоритма. 2. Определите основную операцию 3. Определите сложность алгоритма в наихудшем случае 3.1. Запишите сумму, выражающую количество выполняемых основных операций алгоритма 3.2. Упростите формулу (используя правила суммирования), и определите, к какому классу сложности относится полученная функция 4. Определите сложность в наилучшем случае (если она не совпадает с наихудшей) Анализ нерекурсивных алгоритмов Важные правила и формулы суммирования: n ca i i k n a i k i n c ai i k n n i k ik bI ai bi n 1 n k 1 i k nn 1 i 2 i 1 n Анализ нерекурсивных алгоритмов Пример 1. Задача поиска наибольшего элемента в массиве из n чисел. maxval := a[0]; for i := 1 to n-1 do if ( a[i] > maxval ) then maxval := a[i]; Размер входных данных = n, основная операция = сравнение, сложность в наихудшем и наилучшем случае одинаковая. n 1 C n 1 (n 1) 1 1 n 1 On i 1 Ответ: сложность алгоритма линейная Анализ нерекурсивных алгоритмов Пример 2. Задача проверки уникальности элементов в массиве из n чисел. for i := 0 to n-2 do for j := i + 1 to n-1 do if ( a[i] = a[j] ) then return false; return true; Основная операция = сравнение. Размер входных данных = n Сложность в наихудшем и наилучшем случае различная Анализ нерекурсивных алгоритмов n 2 n 1 n2 i 0 j i 1 i 0 Cworst n 1 n 1 i 1 1 n2 n2 n2 i 0 i 0 i 0 n 1 i n 1 i n 2 n 1 n 11 n2 2 n 2 n 1 n 1n 2 n 1 O n2 2 2 i 0 Cbest n 1 O1 Ответ: сложность алгоритма в наихудшем случае квадратичная, в наилучшем - константная Анализ нерекурсивных алгоритмов Пример 3. Задача умножения двух квадратных матриц размером n на n. for (int i=0; i < n; i++) for (int j=0; j < n; j++) { С[i][j] = 0; for (int k=0; k < n; k++) С[i][j] = С[i][j] + A[i][k] * B[k][j]; } Основная операция = умножение. Размер входных данных = n Анализ нерекурсивных алгоритмов Определите сложность в наихудшем и наилучшем случае Сложность в наихудшем и наилучшем случае одинаковая. n n n C n 1 n3 i 0 j 0 k 0 Ответ: сложность алгоритма кубическая Упражнения 1. В массиве вещественных чисел A(n) подсчитать количество отрицательных и сумму положительных элементов. 2. В массиве вещественных чисел A(n) от каждого из элементов отнять среднее арифметическое всех элементов массива. 3. Дана матрица в виде массива A(n,k). Найти строку, в которой наибольшее количество положительных чисел. 4. Дан массив A(n). Все нулевые элементы этого массива поместить в начало массива B(n). Подсчитать количество нулевых элементов.