Память или время?


Многие алгоритмы предлагают выбор между объёмом памяти и скоростью. Задачу можно решить быстро, использую большой объём памяти, или медленнее, занимая меньший объём.
Типичным примером в данном случае служит алгоритм поиска кратчайшего пути. Представив кару города в виде сети, можно написать алгоритм для определения кратчайшего расстояния между двумя любыми точками этой сети. Чтобы не вычислять эти расстояния всякий раз, когда они нам нужны, мы можем вывести кратчайшие расстояния между всеми точками и сохранить результаты в таблице. Когда нам понадобится узнать кратчайшее расстояние между двумя заданными точками, мы можем просто взять готовое расстояние из таблицы.
Результат будет получен мгновенно, но это потребует огромного объёма памяти. Карта большого города может содержать десятки тысяч точек. Тогда, описанная выше таблица, должна содержать более 10 млрд. ячеек. Т.е. для того, чтобы повысить быстродействие алгоритма, необходимо использовать дополнительные 10 Гб памяти.


Из этой зависимости проистекает идея объёмно-временной эффективности или сложности. При таком подходе алгоритм оценивается, как с точки зрении скорости выполнения, так и с точки зрения потреблённой памяти.
Мы будем уделять основное внимание временной сложности, но, тем не менее, обязательно будем оговаривать и объём потребляемой памяти.

 

Встает вопрос: Как измерить временную сложность, эффективность алгоритма? Что взять за меру, за единицу измерения временной сложности алгоритма?

Очевидно, что это время выполнения алгоритма зависит от объема входных данных (параметра ).

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

С увеличением быстродействия компьютеров возрастают и значения параметров, для которых работа того или иного алгоритма завершается за приемлемое время. Таким образом, увеличивается среднее значение величины , и, следовательно, возрастает величина отношения времен выполнения быстрого и медленного алгоритмов. Чем быстрее компьютер, тем больше относительный проигрыш при использовании плохого алгоритма!

При сравнении различных алгоритмов важно знать, как их сложность зависит от объёма входных данных. Допустим, при сортировке одним методом обработка тысячи чисел занимает 1 с., а обработка миллиона чисел – 10 с., при использовании другого алгоритма может потребоваться 2 с. и 5 с. соответственно. В таких условиях нельзя однозначно сказать, какой алгоритм лучше.

 

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

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

В общем случае сложность алгоритма можно оценить по порядку величины. Алгоритм имеет сложность O(f(n)), если при увеличении размерности входных данных N, время выполнения алгоритма возрастает с той же скоростью, что и функция f(N).

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

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

Например, если время работы алгоритма прямо пропорционально количеству элементов (удвоение объема входных данных в два раза увеличивает время работы), сложность алгоритма записывается в виде О(n). Говорим, что алгоритм имеет порядок сложности n или линейную сложность, т.е. время выполнения алгоритма линейно зависит от n.

Если время работы не зависит от объема входных данных, алгоритм обладает сложностью O(1).

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

 

Таблица 1. Типичные варианты сложности
Тип Обозначение Описание
Постоянная сложность Сложность вида log(log(N)) O(1) O(log(log(N)) Время работы не зависит от количества элементов    
Логарифмическая сложность O(log(n)) O(N^C), 0<C<1 Время работы возрастает в логарифмической зависимости от количества элементов    
Линейная сложность O(n) Время работы возрастает прямо пропорционально количеству элементов
Сложность n-log-n O(n*log(n)) Время работы возрастает как произведение линейной и логарифмической зависимостей от количества элементов
Квадратичная сложность Кубическая сложность Полиномиальная сложность Экспоненциальная сложность
   
 
 
 


Сложность вида N!