9. Сложность алгоритмов и нотация big-O.

Сложность алгоритма — это характеристика того, как быстро (или сколько памяти) алгоритм использует в зависимости от размера входных данных nnn.

Big-O описывает асимптотическое поведение алгоритма — как он себя ведёт при больших входах, игнорируя константы и незначительные слагаемые.

Обозначается как:

T(n)=O(f(n))

Где:

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

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

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

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

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

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

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

Вычислительная сложность алгоритма (computational complexity) - это оценка количества операций выполняемых алгоритмом в зависимости от размера его входных данных.

При асимптотическом анализе вычислительной сложности алгоритма (asymptotic computational complexity) рассматривается поведение алгоритма при n → ∞.

Причины

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

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

Big-O описывает, как изменяется количество базовых операций в зависимости от размера входных данных при их росте. Так как различное оборудование выполняет вычисления с разной скоростью, невозможно точно определить время работы алгоритма без учета характеристик конкретного компьютера. Однако нас больше интересует не абсолютное время работы функции, а то, как оно изменяется при увеличении 𝑛, поскольку это позволяет оценить производительность независимо от аппаратного обеспечения. При больших значениях 𝑛 наибольшее влияние оказывает член с наивысшей степенью, поэтому в нотации Big-O оставляют только его. Кроме того, константные коэффициенты “не имеют значения” и также отбрасываются.

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

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

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

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

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

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

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

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