Uploaded by sen

Big O notation

advertisement
Введение:
O-символика
Александр Куликов
Онлайн-курс «Алгоритмы: теория и практика. Методы»
http://stepic.org/217
Время работы
Функция FibArray(n)
создать массив F [0 . . . n]
F [0] ← 0
F [1] ← 1
для i от 2 до n:
F [i] ← F [i − 1] + F [i − 2]
вернуть F [n]
2 / 13
Время работы
Функция FibArray(n)
создать массив F [0 . . . n]
F [0] ← 0
F [1] ← 1
для i от 2 до n:
F [i] ← F [i − 1] + F [i − 2]
вернуть F [n]
Функция выполняет 2n + 2 строк кода (4 + 2 · (n − 1)), но
действительно ли это отражает время работы алгоритма?
2 / 13
Построчно
Разные строки занимают разное время:
F [0] ← 0
присваивание
3 / 13
Построчно
Разные строки занимают разное время:
F [0] ← 0
присваивание
для i от 2 до n
инкрементирование i (сложение и присваивание)
проверка условия
3 / 13
Построчно
Разные строки занимают разное время:
F [0] ← 0
присваивание
для i от 2 до n
инкрементирование i (сложение и присваивание)
проверка условия
создание массива F [0 . . . n]
выделение памяти
3 / 13
Построчно
Разные строки занимают разное время:
F [0] ← 0
присваивание
для i от 2 до n
инкрементирование i (сложение и присваивание)
проверка условия
создание массива F [0 . . . n]
выделение памяти
F [i] ← F [i − 1] + F [i − 2]
доступ к элементу
сложение (возможно, длинных чисел)
присваивание
3 / 13
Точное время работы
Точное время работы зависит от многих факторов:
тактовая частота процессора
архитектура
компилятор
устройство иерархии памяти
4 / 13
Точное время работы
Точное время работы зависит от многих факторов:
тактовая частота процессора
архитектура
компилятор
устройство иерархии памяти
Необходим способ измерения времени работы, не
зависящий от данных факторов.
4 / 13
O-символика
Определение
Пусть f , g : N → R>0 . Говорим, что f растёт не быстрее g
и пишем f (n) = O(g (n)) или f ⪯ g , если существует такая
константа c > 0, что f (n) ≤ c · g (n) для всех n ∈ N.
5 / 13
O-символика
Определение
Пусть f , g : N → R>0 . Говорим, что f растёт не быстрее g
и пишем f (n) = O(g (n)) или f ⪯ g , если существует такая
константа c > 0, что f (n) ≤ c · g (n) для всех n ∈ N.
Пример
3n2 + 5n + 2 = O(n2 ), поскольку при n ≥ 1 выполнено
3n2 + 5n + 2 ≤ 3n2 + 5n2 + 2n2 = 10n2 .
5 / 13
Скорость роста
3n2 + 5n + 2 имеет ту же скорость роста, что и n2 .
10
9
8
7
6
5
4
3
2
1
3n2 +5n+2
n2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
6 / 13
Использования O-символики
Мы будем использовать O-символику для оценки времени
работы алгоритмов.
7 / 13
Использования O-символики
Мы будем использовать O-символику для оценки времени
работы алгоритмов. Преимущества:
характеризует зависимость времени работы от
размера входных данных
более простые оценки (O(n2 ) вместо 3n2 + 5n + 2)
упрощённый анализ (не думаем, сколько в
действительности занимает каждая отдельная
операция)
не зависит от машины, на которой запускается
алгоритм
7 / 13
Использования O-символики
Мы будем использовать O-символику для оценки времени
работы алгоритмов. Преимущества:
характеризует зависимость времени работы от
размера входных данных
более простые оценки (O(n2 ) вместо 3n2 + 5n + 2)
упрощённый анализ (не думаем, сколько в
действительности занимает каждая отдельная
операция)
не зависит от машины, на которой запускается
алгоритм
Недостатки:
O-символика скрывает константные множители,
которые на практике могут оказаться очень важными
O-символика говорит только про скорость роста
7 / 13
Связанные определения
Определение
Пусть f , g : N → R>0 .
f (n) = Ω(g (n)) и f ⪰ g , если существует
положительная константа c, для которой
f (n) ≥ c · g (n) (f растёт не медленнее g )
f (n) = Θ(g (n)) и f ≍ g , если f = O(g ) и f = Ω(g )
(f и g имеют одинаковую скорость роста)
f (n) = o(g (n)) и f ≺ g , если f (n)/g (n) → 0 при
n → ∞ (f растёт медленнее g ).
8 / 13
Общие правила
Постоянные множители можно опускать:
2
7n3 = Θ(n3 ), n3 = Θ(n2 )
9 / 13
Общие правила
Постоянные множители можно опускать:
2
7n3 = Θ(n3 ), n3 = Θ(n2 )
Многочлен более высокой степени растёт быстрее:
na ≺ nb при a < b
√
n = O(n2 ), n2 = O(n4 ), n = O(n)
9 / 13
Общие правила
Постоянные множители можно опускать:
2
7n3 = Θ(n3 ), n3 = Θ(n2 )
Многочлен более высокой степени растёт быстрее:
na ≺ nb при a < b
√
n = O(n2 ), n2 = O(n4 ), n = O(n)
Экспонента растёт быстрее многочлена:
na ≺ b n √
(a > 0, b > 1):
n
5
n = O( 2 ), n2 = O(3n ), n100 = O(1.1n )
9 / 13
Общие правила
Постоянные множители можно опускать:
2
7n3 = Θ(n3 ), n3 = Θ(n2 )
Многочлен более высокой степени растёт быстрее:
na ≺ nb при a < b
√
n = O(n2 ), n2 = O(n4 ), n = O(n)
Экспонента растёт быстрее многочлена:
na ≺ b n √
(a > 0, b > 1):
n
5
n = O( 2 ), n2 = O(3n ), n100 = O(1.1n )
Многочлен растёт быстрее логарифма:
(log n)a ≺ nb √
(a, b > 0):
(log n)3 = O( n), n log n = O(n2 )
9 / 13
Общие правила
Постоянные множители можно опускать:
2
7n3 = Θ(n3 ), n3 = Θ(n2 )
Многочлен более высокой степени растёт быстрее:
na ≺ nb при a < b
√
n = O(n2 ), n2 = O(n4 ), n = O(n)
Экспонента растёт быстрее многочлена:
na ≺ b n √
(a > 0, b > 1):
n
5
n = O( 2 ), n2 = O(3n ), n100 = O(1.1n )
Многочлен растёт быстрее логарифма:
(log n)a ≺ nb √
(a, b > 0):
(log n)3 = O( n), n log n = O(n2 )
Медленнее растущие слагаемые можно опускать :
(f + g = O(max(f , g )))
n2 + n = O(n2 ), 2n + n9 = O(2n )
9 / 13
Часто используемые функции
log n ≺
√
n ≺ n ≺ n log n ≺ n2 ≺ 2n
10 / 13
Часто используемые функции
log n ≺
√
n ≺ n ≺ n log n ≺ n2 ≺ 2n
16
14
12
10
8
6
4
2
2
4
6
8
10
Часто используемые функции
log n ≺
√
n ≺ n ≺ n log n ≺ n2 ≺ 2n
16
128
14
112
12
96
10
80
8
64
6
48
4
32
2
16
2
4
6
8
10
2
4
6
10 / 13
Время в зависимости от размера
входа
При скорости 109 операций в секунду
n2
2n
n = 20 1 сек 1 сек
n = 50 1 сек 1 сек
n = 102 1 сек 1 сек
n = 106 1 сек 1 сек
n = 109 1 сек 30 сек
1 сек
1 сек
1 сек
17 мин
30 лет
1 сек
13 дней
4 · 1013 лет
109
104,5
30
n
макс n для 1 сек
n log n
107
11 / 13
Скорость роста на практике
Операция
Время работы
12 / 13
Скорость роста на практике
Операция
создать массив F [0 . . . n]
Время работы
Θ(n)
12 / 13
Скорость роста на практике
Операция
создать массив F [0 . . . n]
F [0] ← 0
Время работы
Θ(n)
Θ(1)
12 / 13
Скорость роста на практике
Операция
создать массив F [0 . . . n]
F [0] ← 0
F [1] ← 1
Время работы
Θ(n)
Θ(1)
Θ(1)
12 / 13
Скорость роста на практике
Операция
создать массив F [0 . . . n]
F [0] ← 0
F [1] ← 1
для i от 2 до n:
Время работы
Θ(n)
Θ(1)
Θ(1)
цикл, Θ(n) итераций
12 / 13
Скорость роста на практике
Операция
создать массив F [0 . . . n]
F [0] ← 0
F [1] ← 1
для i от 2 до n:
F [i] ← F [i − 1] + F [i − 2]
Время работы
Θ(n)
Θ(1)
Θ(1)
цикл, Θ(n) итераций
Θ(n)
12 / 13
Скорость роста на практике
Операция
создать массив F [0 . . . n]
F [0] ← 0
F [1] ← 1
для i от 2 до n:
F [i] ← F [i − 1] + F [i − 2]
вернуть F [n]
Время работы
Θ(n)
Θ(1)
Θ(1)
цикл, Θ(n) итераций
Θ(n)
Θ(1)
12 / 13
Скорость роста на практике
Операция
создать массив F [0 . . . n]
F [0] ← 0
F [1] ← 1
для i от 2 до n:
F [i] ← F [i − 1] + F [i − 2]
вернуть F [n]
Время работы
Θ(n)
Θ(1)
Θ(1)
цикл, Θ(n) итераций
Θ(n)
Θ(1)
Итого:
Θ(n) + Θ(1) + Θ(1) + Θ(n) · Θ(n) + Θ(1) = Θ(n2 ).
12 / 13
Заключение
С одной стороны, O-символика позволяет оценить
ситуацию в первом приближении, игнорируя ненужные
детали. С другой — O-символика заодно игнорирует и
некоторые детали, которые на практике оказываются
очень важными.
13 / 13
Download