Intro And Samples

546 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
546
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Intro And Samples

  1. 1. Несложно о сложности. Примеры алгоритмов. Н.Н. Кузюрин С.А. Фомин 10 октября 2008 г. 1 / 86
  2. 2. История алгоритмов Понятие алгоритма известно с незапамятных времен Алгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э. Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э. Формализация понятия — 1930–1940 годы. Курт Гёдель ⇒ «неполнота формальной арифметики», 1931. Алан Тьюринг ⇒ «halting problem», 1936. Эмиль Пост ⇒ «машина Поста», 1936. Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary Number Theory», 1936. Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943. 2 / 86
  3. 3. История алгоритмов Понятие алгоритма известно с незапамятных времен Алгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э. Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э. Формализация понятия — 1930–1940 годы. Курт Гёдель ⇒ «неполнота формальной арифметики», 1931. Алан Тьюринг ⇒ «halting problem», 1936. Эмиль Пост ⇒ «машина Поста», 1936. Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary Number Theory», 1936. Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943. 3 / 86
  4. 4. История алгоритмов Понятие алгоритма известно с незапамятных времен Алгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э. Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э. Формализация понятия — 1930–1940 годы. Курт Гёдель ⇒ «неполнота формальной арифметики», 1931. Алан Тьюринг ⇒ «halting problem», 1936. Эмиль Пост ⇒ «машина Поста», 1936. Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary Number Theory», 1936. Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943. 4 / 86
  5. 5. История алгоритмов Понятие алгоритма известно с незапамятных времен Алгоритм Евклида (Euclidean algorithm) — 500-300 гг. д.н.э. Решето Эратосфена (Sieve of Eratosthenes) — 300-200 гг. д.н.э. Формализация понятия — 1930–1940 годы. Курт Гёдель ⇒ «неполнота формальной арифметики», 1931. Алан Тьюринг ⇒ «halting problem», 1936. Эмиль Пост ⇒ «машина Поста», 1936. Алонзо Чёрч ⇒ «An Unsolvable Problem of Elementary Number Theory», 1936. Стивен Клини ⇒ «Тезис Черча-Тьюринга», 1943. 5 / 86
  6. 6. Теория сложности Ресурсные ограничения Время Память Объем коммуникаций Переборные алгоритмы Пригодны для любой задачи разрешения, но время работы растет экспоненциально. Теория сложности Формулирует алгоритмические задачи. Для каждой задачи ищет: Эффективные алгоритмы — верхние оценки затрат (времени, памяти, . . .) Доказательства сложности — нижние оценки затрат. 6 / 86
  7. 7. Теория сложности Ресурсные ограничения Время Память Объем коммуникаций Переборные алгоритмы Пригодны для любой задачи разрешения, но время работы растет экспоненциально. Теория сложности Формулирует алгоритмические задачи. Для каждой задачи ищет: Эффективные алгоритмы — верхние оценки затрат (времени, памяти, . . .) Доказательства сложности — нижние оценки затрат. 7 / 86
  8. 8. Теория сложности Ресурсные ограничения Время Память Объем коммуникаций Переборные алгоритмы Пригодны для любой задачи разрешения, но время работы растет экспоненциально. Теория сложности Формулирует алгоритмические задачи. Для каждой задачи ищет: Эффективные алгоритмы — верхние оценки затрат (времени, памяти, . . .) Доказательства сложности — нижние оценки затрат. 8 / 86
  9. 9. Обозначения 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 / 86
  10. 10. Обозначения 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. 10 / 86
  11. 11. Тривиальное вычисление y = x n mod m 13 16 47 13 28 35 def mod_exp (x, n, m) : 32 print x, n, m 40 y ←1 3 for i ∈ range (n) : 39 y ←y ∗x %m 37 11 print y 2 return y 26 9 Количество умножений — O(n) 23 17 33 6 y = 13^16 (mod 47) = 6 11 / 86
  12. 12. Разумное вычисление y = x n mod m k k i i i xn = x i=0 ai 2 = x ai 2 = x2 i=0 {i:ai >0} def mod_exp (x, n, m) : print x, n, m 13 16 47 y ←1 28 8 1 X ←x 32 4 1 N←n 37 2 1 while N > 0 : 6 1 1 if N % 2 = 1 : 36 0 6 y ←y ∗X %m y = 13^16 (mod 47) = 6 X ←X ∗X %m N ← N/2 Количество арифметических print X , N, y операций — O(log(n)). return y Длина (бит) Умножений в алг. 1 Умножений в алг. 2 56 256 ≈ 7.2 · 1016 ≈ 100 128 2128 ≈ 3.4 · 1038 ≈ 130 12 / 86
  13. 13. Вычисление факториала y = n! mod m def factorial (n, m) : print n, m 13 131 y ←1 1 for i ∈ range (1, n + 1) : 2 y ←y ∗i %m 6 print y 24 return y 120 65 Количество умножений — O(n). 62 Временная сложность измеряется 103 относительно длины входа: 10 log n + log m. 100 Поэтому cложность 52 экспоненциальна ! 100 Возможно ли лучше — открытая 121 проблема. y =13! mod 131 = 121 13 / 86
  14. 14. Дискретный логарифм Задача «Дискретный логарифм» (Discrete logarithm) Даны натуральные a, b, и p — нечетное простое число. Найти минимальный x, такой, что ax ≡ b (mod p). Вычисление дискретного логарифма является очень сложной задачей. Самые быстрые из известных алгоритмов требуют сверхполиномиального времени. На этом свойстве односторонней вычислимости модульной экспоненты основано множество алгоритмов современной криптографии. 14 / 86
  15. 15. Дискретный логарифм Задача «Дискретный логарифм» (Discrete logarithm) Даны натуральные a, b, и p — нечетное простое число. Найти минимальный x, такой, что ax ≡ b (mod p). Вычисление дискретного логарифма является очень сложной задачей. Самые быстрые из известных алгоритмов требуют сверхполиномиального времени. На этом свойстве односторонней вычислимости модульной экспоненты основано множество алгоритмов современной криптографии. 15 / 86
  16. 16. Дискретный логарифм Задача «Дискретный логарифм» (Discrete logarithm) Даны натуральные a, b, и p — нечетное простое число. Найти минимальный x, такой, что ax ≡ b (mod p). Вычисление дискретного логарифма является очень сложной задачей. Самые быстрые из известных алгоритмов требуют сверхполиномиального времени. На этом свойстве односторонней вычислимости модульной экспоненты основано множество алгоритмов современной криптографии. 16 / 86
  17. 17. Наибольший общий делитель Задача «Наибольший общий делитель» Для заданных натуральных a и b найти максимальное q, для которого . . a . q и b . q (a и b кратны q). . . 17 / 86
  18. 18. Алгоритм Евклида Базовое соотношение gcd(a, b) = gcd(a, r ), b = at + r , 0 ≤ r < a. Calculating gcd(123456, 6122256): 123456 6122256 72912 123456 50544 72912 def gcd (a, b) : 22368 50544 5808 22368 print a, b 4944 5808 if a = 0 : 864 4944 return b 624 864 240 624 return gcd (b % a, a) 144 240 96 144 48 96 0 48 gcd(123456, 6122256) = 48 18 / 86
  19. 19. Алгоритм Евклида Базовое соотношение gcd(a, b) = gcd(a, r ), b = at + r , 0 ≤ r < a. Calculating gcd(123456, 6122256): 123456 6122256 72912 123456 50544 72912 def gcd (a, b) : 22368 50544 5808 22368 print a, b 4944 5808 if a = 0 : 864 4944 return b 624 864 240 624 return gcd (b % a, a) 144 240 96 144 48 96 0 48 gcd(123456, 6122256) = 48 19 / 86
  20. 20. Алгоритм Евклида: Время выполнения Лемма Время работы алгоритма Евклида — 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 После log(ab) итераций ab станет нулем. 5 ab = 0 → a = 0 → НОД найден. 20 / 86
  21. 21. Алгоритм Евклида: Время выполнения Лемма Время работы алгоритма Евклида — 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 После log(ab) итераций ab станет нулем. 5 ab = 0 → a = 0 → НОД найден. 21 / 86
  22. 22. Алгоритм Евклида: Время выполнения Лемма Время работы алгоритма Евклида — 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 После log(ab) итераций ab станет нулем. 5 ab = 0 → a = 0 → НОД найден. 22 / 86
  23. 23. Алгоритм Евклида: Время выполнения Лемма Время работы алгоритма Евклида — 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 После log(ab) итераций ab станет нулем. 5 ab = 0 → a = 0 → НОД найден. 23 / 86
  24. 24. Алгоритм Евклида: Время выполнения Лемма Время работы алгоритма Евклида — 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 После log(ab) итераций ab станет нулем. 5 ab = 0 → a = 0 → НОД найден. 24 / 86
  25. 25. Алгоритм Евклида: Время выполнения Лемма Время работы алгоритма Евклида — 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 После log(ab) итераций ab станет нулем. 5 ab = 0 → a = 0 → НОД найден. 25 / 86
  26. 26. Задача Коммивояжера Задача «Коммивояжер», «TSPa ». Заданы неориентированный граф из n вершин-городов, и dij ≡ d(vi , vj ) — положительные целые расстояния между городами. Чему равна наименьшая возможная длина кольцевого маршрута, проходящего по одному разу через все города? Т.е. нужно найти минимально возможное значение суммы n−1  min  dpi ,pi+1 + dpn ,p1 , (1) 1 2 . . . n i=1 p∈ . . . . где минимум берется по всем перестановкам p чисел 1, . . . , n. a В англоязычной литературе — Traveling Salesman Problem. 26 / 86
  27. 27. Переборный алгоритм для TSP def TSP_BruteForce (G ) : MinPath ← MinPathLength ← None перебор всех перестановок с фиксированным первым узлом for path ∈ xpermutations (G .nodes ()[1 : ]) : PathLength ← getPathLength (path, G .nodes ()[0]) if ¬MinPathLength ∨ MinPathLength > PathLength : MinPathLength, MinPath ← PathLength, path return MinPath, MinPathLength 27 / 86
  28. 28. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 28 / 86
  29. 29. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 29 / 86
  30. 30. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 30 / 86
  31. 31. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 31 / 86
  32. 32. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 32 / 86
  33. 33. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 33 / 86
  34. 34. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 34 / 86
  35. 35. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 35 / 86
  36. 36. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 36 / 86
  37. 37. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 37 / 86
  38. 38. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 38 / 86
  39. 39. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 39 / 86
  40. 40. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 40 / 86
  41. 41. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 41 / 86
  42. 42. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 42 / 86
  43. 43. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 43 / 86
  44. 44. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 44 / 86
  45. 45. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 45 / 86
  46. 46. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 46 / 86
  47. 47. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 47 / 86
  48. 48. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 48 / 86
  49. 49. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 49 / 86
  50. 50. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 50 / 86
  51. 51. Перебор для TSP Moscow $50 $10 Berlin $30 $60 Kiev $15 $50 $20 $80 $15 NY $120 Minsk 51 / 86
  52. 52. Перебор для TSP [’NY’, ’Moscow’, ’Minsk’, ’Berlin’, ’Kiev’] 205 [’NY’, ’Moscow’, ’Minsk’, ’Kiev’, ’Berlin’] 170 [’NY’, ’Moscow’, ’Berlin’, ’Minsk’, ’Kiev’] 225 [’NY’, ’Moscow’, ’Berlin’, ’Kiev’, ’Minsk’] 275 [’NY’, ’Moscow’, ’Kiev’, ’Minsk’, ’Berlin’] 155 [’NY’, ’Moscow’, ’Kiev’, ’Berlin’, ’Minsk’] 240 [’NY’, ’Minsk’, ’Moscow’, ’Berlin’, ’Kiev’] 295 [’NY’, ’Minsk’, ’Moscow’, ’Kiev’, ’Berlin’] 225 [’NY’, ’Minsk’, ’Berlin’, ’Moscow’, ’Kiev’] 280 Moscow $50 [’NY’, ’Minsk’, ’Berlin’, ’Kiev’, ’Moscow’] 240 $10 [’NY’, ’Minsk’, ’Kiev’, ’Moscow’, ’Berlin’] 245 Berlin $30 [’NY’, ’Minsk’, ’Kiev’, ’Berlin’, ’Moscow’] 275 $60 $15 Kiev [’NY’, ’Berlin’, ’Moscow’, ’Minsk’, ’Kiev’] 210 $50 $20 $80 [’NY’, ’Berlin’, ’Moscow’, ’Kiev’, ’Minsk’] 245 [’NY’, ’Berlin’, ’Minsk’, ’Moscow’, ’Kiev’] 175 $15 NY $120 [’NY’, ’Berlin’, ’Minsk’, ’Kiev’, ’Moscow’] 155 Minsk [’NY’, ’Berlin’, ’Kiev’, ’Moscow’, ’Minsk’] 225 [’NY’, ’Berlin’, ’Kiev’, ’Minsk’, ’Moscow’] 170 [’NY’, ’Kiev’, ’Moscow’, ’Minsk’, ’Berlin’] 175 [’NY’, ’Kiev’, ’Moscow’, ’Berlin’, ’Minsk’] 280 [’NY’, ’Kiev’, ’Minsk’, ’Moscow’, ’Berlin’] 210 [’NY’, ’Kiev’, ’Minsk’, ’Berlin’, ’Moscow’] 225 [’NY’, ’Kiev’, ’Berlin’, ’Moscow’, ’Minsk’] 295 52 / 86
  53. 53. Кратчайшие пути в графе Задача «Кратчайший путь в графе»a . Заданы n вершин графа (узлов сети) v1 , v2 , . . . , vn и положительные целые длины дуг dij ≡ d(vi , vj ) между ними. Нужно для всех k ∈ (2 . . . n) найти минимальную длину пути из v1 в vk . a В англоязычной литературе — Shortest Path Problem. 53 / 86
  54. 54. Кратчайшие пути в графе Важное свойство Если у нас есть кратчайший путь от v до w , проходящий через вершину y , назовем его (v → w )∗ , то его первая часть от v до y , (v → y )∗ , тоже будет кратчайшим путем. Доказательство. Если бы существовал бы путь (v → y )! длины меньшей, чем (v → y )∗ , то можно было бы улучшить оптимальный путь (v → w )∗ , заменив в нем (v → y )∗ на (v → y )! . 54 / 86
  55. 55. Алгоритм Дейкстры def dijkstra (G , startNode) : Visited ← {} # хэш (узел → стоимость) посещенных вершин ToVisit ← {startNode : 0} # соседи посещенных (уз. → стоим.) Paths ← {startNode : [startNode]} # узел → кратчайший путь while ToVisit : # пока есть куда стремиться v ← argmin (ToVisit) # выбираем ближайшую Visited[v ] ← ToVisit[v ] # фиксируем откуда пришли в v del ToVisit[v ] # кратчайший путь к v найден for w ∈ G .neighbors (v ) : # для всех соседей вершины v if (w ∈ Visited) : # еще не нашли кратчайший путь обновляем кратчайшие пути vwLength ← Visited[v ] + G .get_edge (v , w ) if (w ∈ ToVisit) ∨ (vwLength < ToVisit[w ]) : ToVisit[w ] ← vwLength # обновляем цену Paths[w ] ← Paths[v ] + [w ] # посещения соседа return (Visited, Paths) 55 / 86
  56. 56. Выполнение алгоритма Дейкстры Munich $10 Kiev $30 $15 Berlin $20 $15 $10 $20 Minsk $50 $50 Start $0 $15 Moscow $15 NY $60 $30 $105 Vladivostok Итерация № 1 56 / 86
  57. 57. Выполнение алгоритма Дейкстры Munich $10 Kiev $30 $15 Berlin $20 $15 $10 $20 Minsk $50 $50 Start $0 $15 Moscow NY $15 $60 $75 $30 $105 Vladivostok $120 Итерация № 2 57 / 86
  58. 58. Выполнение алгоритма Дейкстры Munich $10 Kiev $30 $15 Berlin $20 $15 $10 $20 Minsk $50 $50 Start $0 $15 Moscow NY $15 $60 $75 $30 $105 Vladivostok $120 Итерация № 3 58 / 86
  59. 59. Выполнение алгоритма Дейкстры Munich $30 $10 Kiev $30 $15 Berlin $20 $15 $10 $20 $50 Minsk $50 Start $0 $15 Moscow NY $15 $60 $70 $105 $30 Vladivostok $120 Итерация № 4 59 / 86
  60. 60. Выполнение алгоритма Дейкстры Munich $30 $10 Kiev $30 $15 Berlin $20 $15 $10 $20 $50 Minsk $50 Start $0 $15 Moscow NY $15 $60 $70 $105 $30 Vladivostok $120 Итерация № 5 60 / 86
  61. 61. Выполнение алгоритма Дейкстры Munich $30 $10 Kiev $30 $15 Berlin $20 $15 $10 $20 $50 Minsk $50 Start $0 $15 Moscow NY $15 $60 $70 $105 $30 Vladivostok $100 Итерация № 6 61 / 86
  62. 62. Выполнение алгоритма Дейкстры Munich $30 $10 Kiev $30 $15 Berlin $20 $15 $10 $20 $50 Minsk $50 Start $0 $15 Moscow NY $15 $60 $70 $105 $30 Vladivostok $100 Итерация № 7 62 / 86
  63. 63. Трудоемкость алгоритма Дейкстры Лемма Трудоемкость алгоритма Дейкстры составляет O(n2 ) операций, где n — число вершин. Доказательство. 1 Внешний цикл по вершинам дает множитель n. 2 Внутренний цикл содержит выбор минимального элемента — O(n) + пересчет оценок длин для соседей выбранного узла — O(n). 3 Итого — O(n2 ). 63 / 86
  64. 64. Трудоемкость алгоритма Дейкстры Лемма Трудоемкость алгоритма Дейкстры составляет O(n2 ) операций, где n — число вершин. Доказательство. 1 Внешний цикл по вершинам дает множитель n. 2 Внутренний цикл содержит выбор минимального элемента — O(n) + пересчет оценок длин для соседей выбранного узла — O(n). 3 Итого — O(n2 ). 64 / 86
  65. 65. Трудоемкость алгоритма Дейкстры Лемма Трудоемкость алгоритма Дейкстры составляет O(n2 ) операций, где n — число вершин. Доказательство. 1 Внешний цикл по вершинам дает множитель n. 2 Внутренний цикл содержит выбор минимального элемента — O(n) + пересчет оценок длин для соседей выбранного узла — O(n). 3 Итого — O(n2 ). 65 / 86
  66. 66. Кратчайшие пути в графе с отрицательными весами Задача «Кратчайшие пути с отрицательными расстояниями». Задан ориентированный граф G = (V , E ) и весовая функция на дугах we : e → Z , отображающая ребра в целые числа, такая, что в графе нет цикла отрицательной длины. Найти минимальные длины путей между всеми парами вершин. 66 / 86
  67. 67. Алгоритм Флойда-Уоршолла for k ∈ range (N) : # N — размер матрицы DD ← array (D) # Сохраняем Dk−1 в DD for v1 ∈ range (N) : for v2 ∈ range (N) : D[v1, v2] ← min (DD[v1, v2], DD[v1, k] + DD[k, v2]) 67 / 86
  68. 68. Выполнение алгоритма Флойда-Уоршолла $15 $10 Minsk(2) $-5 $20 $15 Moscow(1) $50 $10 $30 Kiev(4) $30 Berlin(3) $80 $60 NY(0) $50 k=0 (NY) NY Moscow Minsk Berlin Kiev NY 0 ∞ ∞ ∞ 80 Moscow 60 0 -5 50 10 Minsk ∞ 10 0 ∞ ∞ Berlin 50 30 20 0 30 Kiev ∞ 15 15 ∞ 0 68 / 86
  69. 69. Выполнение алгоритма Флойда-Уоршолла $15 $10 Minsk(2) $-5 $20 $15 Moscow(1) $50 $10 $30 Kiev(4) $30 Berlin(3) $80 $60 NY(0) $50 k=1 NY Moscow Minsk Berlin Kiev (Moscow) NY 0 ∞ ∞ ∞ 80 Moscow 60 0 -5 50 10 Minsk ∞⇒70 10 0 ∞⇒60 ∞⇒20 Berlin 50 30 20 0 30 Kiev ∞⇒75 15 15⇒10 ∞⇒65 0 69 / 86
  70. 70. Выполнение алгоритма Флойда-Уоршолла $15 $10 Minsk(2) $-5 $20 $15 Moscow(1) $50 $10 $30 Kiev(4) $30 Berlin(3) $80 $60 NY(0) $50 k=2 (Minsk) NY Moscow Minsk Berlin Kiev NY 0 ∞ ∞ ∞ 80 Moscow 60 0 -5 50 10 Minsk 70 10 0 60 20 Berlin 50 30 20 0 30 Kiev 75 15 10 65 0 70 / 86
  71. 71. Выполнение алгоритма Флойда-Уоршолла $15 $10 Minsk(2) $-5 $20 $15 Moscow(1) $50 $10 $30 Kiev(4) $30 Berlin(3) $80 $60 NY(0) $50 k=3 (Berlin) NY Moscow Minsk Berlin Kiev NY 0 ∞ ∞ ∞ 80 Moscow 60 0 -5 50 10 Minsk 70 10 0 60 20 Berlin 50 30 20 0 30 Kiev 75 15 10 65 0 71 / 86
  72. 72. Выполнение алгоритма Флойда-Уоршолла $15 $10 Minsk(2) $-5 $20 $15 Moscow(1) $50 $10 $30 Kiev(4) $30 Berlin(3) $80 $60 NY(0) $50 k=4 (Kiev) NY Moscow Minsk Berlin Kiev NY 0 ∞⇒95 ∞⇒90 ∞⇒145 80 Moscow 60 0 -5 50 10 Minsk 70 10 0 60 20 Berlin 50 30 20 0 30 Kiev 75 15 10 65 0 72 / 86
  73. 73. Минимальное остовное дерево Задача «Минимальное остовное дерево» (Minimum Spanning Tree) Задан связный неориентированный граф G = (V , E ), где V —множество вершин, |V | = n, E —множество ребер между ними, и весовая функция w : E → Z +. Иными словами, есть n вершин v1 , . . . , vn и положительные целые веса дуг wij ≡ w (vi , vj )a между ними. Требуется найти наименьший возможный вес остовного дерева, т.е. min w (vi , vj ), (2) (i,j)∈T где минимум берется по всем остовным деревьям на n вершинах (по всем множествам T из (n − 1) дуг, связывающим все n вершин в единую сеть). a Можно вводить веса на ребрах, как we , e ∈ E . 73 / 86
  74. 74. Алгоритм Прима 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 ∈ MST : # которые еще не в MST обновляем стоимость включения в MST if w ∈ ToVisit ∨ G .get_edge (v , w ) < ToVisit[w ] : ToVisit[w ] ← G .get_edge (v , w ) # кандидат Predecessor[w ] ← v return MST 74 / 86
  75. 75. Выполнение алгоритма Прима Berlin ($20) $50 Moscow ($15) $10 $30 Kiev ($15) $60 $$ 2 0 $15 0 5 $80 $15 NY Minsk Start Итерация № 1 Стоимость MST: 0 75 / 86
  76. 76. Выполнение алгоритма Прима Berlin ($20) $50 Moscow $30 $10 $ 5 0$ 2 0 Kiev ($10) $60 $80 $15 $15 NY ($60) Minsk Start Итерация № 2 Стоимость MST: 15 76 / 86
  77. 77. Выполнение алгоритма Прима Berlin ($20) $50 Moscow $10 $30 $50 $20 Kiev $60 $15 $15 $80 NY ($60) Minsk Start Итерация № 3 Стоимость MST: 25 77 / 86
  78. 78. Выполнение алгоритма Прима Berlin $50 Moscow $10 $30 $50 $20 Kiev $60 $15 $15 $80 NY ($50) Minsk Start Итерация № 4 Стоимость MST: 45 78 / 86
  79. 79. Выполнение алгоритма Прима Berlin $50 Moscow $10 $30 $50 $20 Kiev $60 $15 $15 $80 NY Minsk Start Итерация № 5 Стоимость MST: 95 79 / 86
  80. 80. Сортировка Задача «Сортировка» (Sorting) Имеется произвольный массив A : a1 , . . . , an . Tребуется путем сравнений отсортировать этот массив таким образом, чтобы элементы расположились в порядке возрастания (или убывания), то есть ai1 ≤ ai2 ≤ . . . ≤ ain . 80 / 86
  81. 81. Cортировка слиянием def mergesort (L) : M ← len (L)/2 # середина списка if M = 0 : # если список меньше двух элементов return L # сортировать нечего return merge (mergesort (L[ : M]), mergesort (L[M : ])) def merge (A, B) : C ← [] while A ∨ B : # пока оба списка непусты if ¬B ∨ (A ∧ A[0] < B[0]) : C .append (A.pop (0)) # A0 удаляем из A и добавляем в C else : C .append (B.pop (0)) # B0 удаляем из B и добавляем в C return C 81 / 86
  82. 82. Cортировка слиянием: Выполнение 82 / 86
  83. 83. Cортировка слиянием: Упражнения Упражнение Найдите такие упорядоченные последовательности A и B, на которых процедура «merge» выполнит |A| + 1 сравнений. Упражнение Найдите такие упорядоченные последовательности A и B, на которых процедура «merge» выполнит |A| + |B| − 1 сравнений. 83 / 86
  84. 84. Cортировка слиянием: Время выполнения Пусть T (n) — число сравнений, достаточное для сортировки слиянием. T (n) ≤ 2T (n/2) + O(n). Проверим T (n) = cn log2 n: cn log2 n ≤ cn log(n/2) + O(n) = cn log2 n − cn + O(n) Резюме Алгоритм асимптотически оптимален: O(n log n), но использует вспомогательные массивы (не всегда допустимо). 84 / 86
  85. 85. Карта памяти лекции 85 / 86
  86. 86. Интернет поддержка курса http://discopal.ispras.ru/ Вопросы? 86 / 86

×