intro erevan
TRANSCRIPT
Несложно о сложности. Примеры алгоритмов.
Н.Н. Кузюрин С.А. Фомин
10 октября 2008 г.
1 / 46
История алгоритмов
Понятие алгоритма известно с незапамятных временАлгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э.Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э.
Формализация понятия — 1930–1940 годы.Курт Гёдель ⇒ «неполнота формальной арифметики», 1931.Алан Тьюринг ⇒ «halting problem», 1936.Эмиль Пост ⇒ «машина Поста», 1936.Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary NumberTheory», 1936.Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943.
2 / 46
История алгоритмов
Понятие алгоритма известно с незапамятных временАлгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э.Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э.
Формализация понятия — 1930–1940 годы.Курт Гёдель ⇒ «неполнота формальной арифметики», 1931.Алан Тьюринг ⇒ «halting problem», 1936.Эмиль Пост ⇒ «машина Поста», 1936.Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary NumberTheory», 1936.Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943.
3 / 46
История алгоритмов
Понятие алгоритма известно с незапамятных временАлгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э.Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э.
Формализация понятия — 1930–1940 годы.Курт Гёдель ⇒ «неполнота формальной арифметики», 1931.Алан Тьюринг ⇒ «halting problem», 1936.Эмиль Пост ⇒ «машина Поста», 1936.Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary NumberTheory», 1936.Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943.
4 / 46
История алгоритмов
Понятие алгоритма известно с незапамятных временАлгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э.Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э.
Формализация понятия — 1930–1940 годы.Курт Гёдель ⇒ «неполнота формальной арифметики», 1931.Алан Тьюринг ⇒ «halting problem», 1936.Эмиль Пост ⇒ «машина Поста», 1936.Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary NumberTheory», 1936.Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943.
5 / 46
Теория сложности
Ресурсные ограниченияВремяПамятьОбъем коммуникаций
Переборные алгоритмыПригодны для большинства задач дискретной оптимизации, но времяработы растет экспоненциально.
6 / 46
Теория сложности
Ресурсные ограниченияВремяПамятьОбъем коммуникаций
Переборные алгоритмыПригодны для большинства задач дискретной оптимизации, но времяработы растет экспоненциально.
7 / 46
Обозначения
f (n) = O(g(n))
Существует константа C > 0 такая, что начиная с некоторого nвыполнено f (n) ≤ Cg(n).
f (n) = Ω(g(n))
Существует константа C > 0 такая, что начиная с некоторого nвыполнено f (n) ≥ Cg(n).
Описание алгоритмов«Псевдокод» — неполнота, «C/C++/Java» — нечитаемый синтаксиси слабая абстракция.Мы используем популярный и рекомендованный для преподаванияалгоритмов язык Python.
8 / 46
Обозначения
f (n) = O(g(n))
Существует константа C > 0 такая, что начиная с некоторого nвыполнено f (n) ≤ Cg(n).
f (n) = Ω(g(n))
Существует константа C > 0 такая, что начиная с некоторого nвыполнено f (n) ≥ Cg(n).
Описание алгоритмов«Псевдокод» — неполнота, «C/C++/Java» — нечитаемый синтаксиси слабая абстракция.Мы используем популярный и рекомендованный для преподаванияалгоритмов язык Python.
9 / 46
Тривиальное вычисление y = xn mod m
def mod_exp (x , n, m) :print x , n, my ← 1for i ∈ range (n) :
y ← y ∗ x % mprint y
return y
Количество умножений — O(n)
13 16 471328353240339371122692317336y = 13^16 (mod 47) = 6
10 / 46
Разумное вычисление y = xn mod m
xn = x∑k
i=0 ai2i=
k∏i=0
xai2i=
∏{i :ai>0}
x2i
def mod_exp (x , n, m) :print x , n, my ← 1X ← xN ← nwhile N > 0:
if N % 2 = 1:y ← y ∗ X % m
X ← X ∗ X % mN ← N/2print X , N, y
return y
13 16 4728 8 132 4 137 2 16 1 136 0 6y = 13^16 (mod 47) = 6
Количество арифметическихопераций — O(log(n)).
Длина (бит) Умножений в алг. 1 Умножений в алг. 256 256 ≈ 7.2 · 1016 ≈ 100
128 2128 ≈ 3.4 · 1038 ≈ 13011 / 46
Вычисление факториала y = n! mod m
def factorial (n, m) :print n, my ← 1for i ∈ range (1, n + 1):
y ← y ∗ i % mprint y
return y
Количество умножений — O(n).Временная сложность измеряетсяотносительно длины входа:log n + log m.Поэтому cложностьэкспоненциальна !Возможно ли лучше — открытаяпроблема.
13 1311262412065621031010052100121y =13! mod 131 = 121
12 / 46
Дискретный логарифм
Задача
«Дискретный логарифм» (Discrete logarithm) Даны натуральные a, b,и p — нечетное простое число. Найти минимальный x , такой, что
ax ≡ b (mod p).
Вычисление дискретного логарифма является очень сложной задачей.Самые быстрые из известных алгоритмов требуютсверхполиномиального времени.
На этом свойстве односторонней вычислимости модульной экспонентыосновано множество алгоритмов современной криптографии.
13 / 46
Дискретный логарифм
Задача
«Дискретный логарифм» (Discrete logarithm) Даны натуральные a, b,и p — нечетное простое число. Найти минимальный x , такой, что
ax ≡ b (mod p).
Вычисление дискретного логарифма является очень сложной задачей.Самые быстрые из известных алгоритмов требуютсверхполиномиального времени.
На этом свойстве односторонней вычислимости модульной экспонентыосновано множество алгоритмов современной криптографии.
14 / 46
Дискретный логарифм
Задача
«Дискретный логарифм» (Discrete logarithm) Даны натуральные a, b,и p — нечетное простое число. Найти минимальный x , такой, что
ax ≡ b (mod p).
Вычисление дискретного логарифма является очень сложной задачей.Самые быстрые из известных алгоритмов требуютсверхполиномиального времени.
На этом свойстве односторонней вычислимости модульной экспонентыосновано множество алгоритмов современной криптографии.
15 / 46
Наибольший общий делитель
Задача
«Наибольший общий делитель»Для заданных натуральных a и b найти максимальное q, для которого
a... q и b
... q (a и b кратны q).
16 / 46
Алгоритм Евклида
Базовое соотношение
gcd(a, b) = gcd(a, r), b = at + r , 0 ≤ r < a.
def gcd (a, b) :print a, bif a = 0:
return breturn gcd (b % a, a)
Calculating gcd(123456, 6122256):123456 612225672912 12345650544 7291222368 505445808 223684944 5808864 4944624 864240 624144 24096 14448 960 48gcd(123456, 6122256) = 48
17 / 46
Алгоритм Евклида
Базовое соотношение
gcd(a, b) = gcd(a, r), b = at + r , 0 ≤ r < a.
def gcd (a, b) :print a, bif a = 0:
return breturn gcd (b % a, a)
Calculating gcd(123456, 6122256):123456 612225672912 12345650544 7291222368 505445808 223684944 5808864 4944624 864240 624144 24096 14448 960 48gcd(123456, 6122256) = 48
18 / 46
Алгоритм Евклида: Время выполнения
ЛеммаВремя работы алгоритма Евклида — O(log a + log b) арифметическихопераций.
Доказательство.1 Имеем b ≥ a + (b mod a) ≥ 2(b mod a) ≡ 2r .2 Отсюда получаем, что r ≤ b
2 .3 ar ≤ ab/2 (на каждой итерации ab уменьшается вдвое).4 После dlog(ab)e итераций ab станет нулем.5 ab = 0 → a = 0 → НОД найден.
19 / 46
Алгоритм Евклида: Время выполнения
ЛеммаВремя работы алгоритма Евклида — O(log a + log b) арифметическихопераций.
Доказательство.1 Имеем b ≥ a + (b mod a) ≥ 2(b mod a) ≡ 2r .2 Отсюда получаем, что r ≤ b
2 .3 ar ≤ ab/2 (на каждой итерации ab уменьшается вдвое).4 После dlog(ab)e итераций ab станет нулем.5 ab = 0 → a = 0 → НОД найден.
20 / 46
Алгоритм Евклида: Время выполнения
ЛеммаВремя работы алгоритма Евклида — O(log a + log b) арифметическихопераций.
Доказательство.1 Имеем b ≥ a + (b mod a) ≥ 2(b mod a) ≡ 2r .2 Отсюда получаем, что r ≤ b
2 .3 ar ≤ ab/2 (на каждой итерации ab уменьшается вдвое).4 После dlog(ab)e итераций ab станет нулем.5 ab = 0 → a = 0 → НОД найден.
21 / 46
Алгоритм Евклида: Время выполнения
ЛеммаВремя работы алгоритма Евклида — O(log a + log b) арифметическихопераций.
Доказательство.1 Имеем b ≥ a + (b mod a) ≥ 2(b mod a) ≡ 2r .2 Отсюда получаем, что r ≤ b
2 .3 ar ≤ ab/2 (на каждой итерации ab уменьшается вдвое).4 После dlog(ab)e итераций ab станет нулем.5 ab = 0 → a = 0 → НОД найден.
22 / 46
Алгоритм Евклида: Время выполнения
ЛеммаВремя работы алгоритма Евклида — O(log a + log b) арифметическихопераций.
Доказательство.1 Имеем b ≥ a + (b mod a) ≥ 2(b mod a) ≡ 2r .2 Отсюда получаем, что r ≤ b
2 .3 ar ≤ ab/2 (на каждой итерации ab уменьшается вдвое).4 После dlog(ab)e итераций ab станет нулем.5 ab = 0 → a = 0 → НОД найден.
23 / 46
Алгоритм Евклида: Время выполнения
ЛеммаВремя работы алгоритма Евклида — O(log a + log b) арифметическихопераций.
Доказательство.1 Имеем b ≥ a + (b mod a) ≥ 2(b mod a) ≡ 2r .2 Отсюда получаем, что r ≤ b
2 .3 ar ≤ ab/2 (на каждой итерации ab уменьшается вдвое).4 После dlog(ab)e итераций ab станет нулем.5 ab = 0 → a = 0 → НОД найден.
24 / 46
Задача Коммивояжера
Задача
«Коммивояжер», «TSPa». Заданы неориентированный граф из nвершин-городов, и dij ≡ d(vi , vj) — положительные целые расстояниямежду городами.Чему равна наименьшая возможная длина кольцевого маршрута,проходящего по одному разу через все города? Т.е. нужно найтиминимально возможное значение суммы
min
p∈
1 2 . . . n. . . .
n−1∑i=1
dpi ,pi+1 + dpn,p1 , (1)
где минимум берется по всем перестановкам p чисел 1, . . . , n.aВ англоязычной литературе — Traveling Salesman Problem.
25 / 46
Перебор для TSP
N Y
Berlin
$50
Minsk
$120
M o s c o w
$60Kiev
$80
$30
$20
$15
$50
$15
$10
26 / 46
Кратчайшие пути в графе
Задача
«Кратчайший путь в графе»a.Заданы n вершин графа (узлов сети) v1, v2, . . . , vn и положительныецелые длины дуг dij ≡ d(vi , vj) между ними.Нужно для всех k ∈ (2 . . . n) найти минимальную длину пути из v1 в vk .
aВ англоязычной литературе — Shortest Path Problem.
27 / 46
Кратчайшие пути в графе с отрицательными весами
Задача
«Кратчайшие пути с отрицательными расстояниями».Задан ориентированный граф G = (V , E ) и весовая функция на дугахwe : e → Z , отображающая ребра в целые числа, такая, что в графенет цикла отрицательной длины. Найти минимальные длины путеймежду всеми парами вершин.
28 / 46
Алгоритм Флойда-Уоршолла
for k ∈ range (N) : # N — размер матрицыDD← array (D) # Сохраняем Dk−1 в DDfor v1 ∈ range (N) :
for v2 ∈ range (N) :D[v1, v2]← min (DD[v1, v2], DD[v1, k] + DD[k , v2])
29 / 46
Выполнение алгоритма Флойда-Уоршолла
N Y ( 0 )
Kiev(4)$80
M o s c o w ( 1 )
$60
Minsk(2 )$-5
Ber l in (3)
$50
$10
$10
$50
$30
$20
$30
$15
$15
k=0 (NY) NY Moscow Minsk Berlin KievNY 0 ∞ ∞ ∞ 80Moscow 60 0 -5 50 10Minsk ∞ 10 0 ∞ ∞Berlin 50 30 20 0 30Kiev ∞ 15 15 ∞ 0
30 / 46
Выполнение алгоритма Флойда-Уоршолла
N Y ( 0 )
Kiev(4)$80
M o s c o w ( 1 )
$60
Minsk(2 )$-5
Ber l in (3)
$50
$10
$10
$50
$30
$20
$30
$15
$15
k=1(Moscow)
NY Moscow Minsk Berlin Kiev
NY 0 ∞ ∞ ∞ 80Moscow 60 0 -5 50 10Minsk ∞⇒70 10 0 ∞⇒60 ∞⇒20Berlin 50 30 20 0 30Kiev ∞⇒75 15 15⇒10 ∞⇒65 0
31 / 46
Выполнение алгоритма Флойда-Уоршолла
N Y ( 0 )
Kiev(4)$80
M o s c o w ( 1 )
$60
Minsk(2 )$-5
Ber l in (3)
$50
$10
$10
$50
$30
$20
$30
$15
$15
k=2 (Minsk) NY Moscow Minsk Berlin KievNY 0 ∞ ∞ ∞ 80Moscow 60 0 -5 50 10Minsk 70 10 0 60 20Berlin 50 30 20 0 30Kiev 75 15 10 65 0
32 / 46
Выполнение алгоритма Флойда-Уоршолла
N Y ( 0 )
Kiev(4)$80
M o s c o w ( 1 )
$60
Minsk(2 )$-5
Ber l in (3)
$50
$10
$10
$50
$30
$20
$30
$15
$15
k=3 (Berlin) NY Moscow Minsk Berlin KievNY 0 ∞ ∞ ∞ 80Moscow 60 0 -5 50 10Minsk 70 10 0 60 20Berlin 50 30 20 0 30Kiev 75 15 10 65 0
33 / 46
Выполнение алгоритма Флойда-Уоршолла
N Y ( 0 )
Kiev(4)$80
M o s c o w ( 1 )
$60
Minsk(2 )$-5
Ber l in (3)
$50
$10
$10
$50
$30
$20
$30
$15
$15
k=4 (Kiev) NY Moscow Minsk Berlin KievNY 0 ∞⇒95 ∞⇒90 ∞⇒145 80Moscow 60 0 -5 50 10Minsk 70 10 0 60 20Berlin 50 30 20 0 30Kiev 75 15 10 65 0
34 / 46
Минимальное остовное деревоЗадача
«Минимальное остовное дерево» (Minimum Spanning Tree)Задан связный неориентированный граф G = (V , E ), гдеV—множество вершин, |V | = n, E—множество ребер между ними,и весовая функция w : E → Z+. Иными словами, есть n вершинv1, . . . , vn и положительные целые веса дуг wij ≡ w(vi , vj)
aмежду ними.Требуется найти наименьший возможный вес остовного дерева, т.е.
min∑
(i ,j)∈T
w(vi , vj), (2)
где минимум берется по всем остовным деревьям на n вершинах (повсем множествам T из (n − 1) дуг, связывающим все n вершинв единую сеть).
aМожно вводить веса на ребрах, как we , e ∈ E .
35 / 46
Алгоритм Прима
def MST_Prim (G , s) :
MST← {} # мин. остовное дерево, хэш (вершина:предшественник)ToVisit← {s : 0} # хэш, граничащих с MST, (узел:стоимость)Predecessor← {s : s} # хэш: вершины из которых включают другиеwhile ToVisit : # пока есть непосещенные вершины
v ← argmin (ToVisit) # ближайшая достижимая вершинаMST[v ]← Predecessor[v ]; # запоминаем, откуда пришлиdel ToVisit[v ]; del Predecessor[v ]; # больше не посещатьfor w ∈ G .neighbors (v) : # для всех соседей вершины v
if w 6∈ MST : # которые еще не в MSTобновляем стоимость включения в MST
if w 6∈ ToVisit ∨ G .get_edge (v , w) < ToVisit[w ] :
ToVisit[w ]← G .get_edge (v , w) # кандидатPredecessor[w ]← v
return MST
36 / 46
Выполнение алгоритма Прима
N Y
M o s c o w ( $ 1 5 )
$ 6 0
Berl in ($20)
$ 5 0Kiev ($15)
$ 8 0
M i n s k
Start
$ 1 5
$ 5 0
$ 1 0
$ 2 0
$ 1 5
$ 3 0
Итерация № 1 Стоимость MST: 0
37 / 46
Выполнение алгоритма Прима
N Y ( $ 6 0 )
M o s c o w
$ 6 0
Berl in ($20)
$ 5 0 Kiev ($10)
$ 8 0
M i n s k
Start
$ 1 5
$ 5 0
$ 1 0$ 2 0
$ 1 5
$ 3 0
Итерация № 2 Стоимость MST: 1538 / 46
Выполнение алгоритма Прима
N Y ( $ 6 0 )
M o s c o w
$ 6 0
Berl in ($20)
$ 5 0 Kiev
$ 8 0
M i n s k
Start
$ 1 5
$ 5 0
$ 1 0
$ 2 0
$ 1 5
$ 3 0
Итерация № 3 Стоимость MST: 2539 / 46
Выполнение алгоритма Прима
N Y ( $ 5 0 )
M o s c o w
$ 6 0
Berl in
$ 5 0 Kiev
$ 8 0
M i n s k
Start
$ 1 5
$ 5 0
$ 1 0
$ 2 0
$ 1 5
$ 3 0
Итерация № 4 Стоимость MST: 4540 / 46
Выполнение алгоритма Прима
N Y
M o s c o w
$ 6 0
Berl in
$ 5 0 Kiev
$ 8 0
M i n s k
Start
$ 1 5
$ 5 0
$ 1 0
$ 2 0
$ 1 5
$ 3 0
Итерация № 5 Стоимость MST: 9541 / 46
Приближенные алгоритмы
Часто алгоритмы, используемые на практике, не находят точноерешение, а довольствуются нахождением приближенного решения.Такие алгоритмы называются приближенными. Часто приближенныеалгоритмы применяют для решения NP-трудных задач.
Задача«Составление расписаний» Имеется m одинаковых машин и nнезависимых работ с длительностями исполнения t1, . . . , tn.Распределить эти работы по машинам так, чтобы минимизироватьмаксимальную загрузку (загрузка машины равна сумме длительностейработ, приписанных данной машине).
42 / 46
Составление расписаний
Даже для случая m = 2 она остается NP-трудной, поскольку к нейсводится NP-трудная задача о камнях: для заданного множества из nкамней с весами t1, . . . , tn выяснить, можно ли разбить это множествона два так, чтобы суммы весов в них были равны. Это условие можнозаписать в виде булева уравнения:
n∑i=1
xi ti = A/2,
где A =∑n
i=1 ti , xi ∈ {0, 1}.
Традиционный подход к задачам такого рода состоит в использованиипростых эвристик, одну из которых мы сейчас проанализируем.
43 / 46
Составление расписаний
Эвристика: Берется произвольная работа и помещается на машину,имеющую наименьшую загрузку (загрузка равна сумме длин работ наданной машине).Эта эвристика обладает следующим очевидным свойством.
ЛеммаВ любой момент работы этой эвристики разница в загрузке междунаиболее и наименее загруженными машинами не превосходитtmax = maxi ti .
44 / 46
Составление расписанийЛеммаПостроенное расписание отличается от оптимального (по критериюминимизации максимальной загрузки) не более чем в два раза.
Доказательство.Пусть T ∗ — длина оптимального расписания (сумма длин работ нанаиболее загруженной машине), TA — длина расписания, котороепостроено нашей эвристикой, TA
min — сумма длительностей работ нанаименее загруженной машине. Очевидно:
T ∗ ≥ TAmin, T ∗ ≥ tmax .
Оценим качество получаемого расписания:
TA
T ∗≤
TAmin + tmax
T ∗≤ T ∗ + tmax
T ∗≤ 1 +
tmax
T ∗≤ 1 + 1 = 2.
45 / 46
Приближенные алгоритмы: Задача коммивояжера
Предположим, что существует эффективный алгоритм A, который длялюбого входа задачи строит гамильтонов цикл (цикла, проходящегочерез все вершины в графе) веса не более чем в K раз превосходящегооптимум (K = f (n), где n — число вершин графа). Подадим на входалгоритма A набор весов специального вида. Пусть дан произвольныйграф G = (V , E ), |V | = n. Тогда вес ребра e в полном графе зададимформулой: w(e) = 1, если e ∈ E , и w(e) = nK , если e /∈ E .
Если в графе G = (V , E ) есть гамильтонов цикл, то алгоритм долженвыдать число, не превосходящее Kn. Если же гамильтонова цикла в Gнет, то алгоритм выдает число, не меньшее nK + n − 1.Значит, такого алгоритма A не должно существоватьв предположении, что P 6= NP.
46 / 46